mirror of
https://github.com/qlik-oss/nebula.js.git
synced 2025-12-19 17:58:43 -05:00
chore: enable prettier (#88)
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
dist
|
||||
node_modules
|
||||
**/__test__/unit/coverage/*
|
||||
**/__test__/component/coverage/*
|
||||
dist/
|
||||
coverage/
|
||||
node_modules/
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": [
|
||||
"airbnb"
|
||||
],
|
||||
"extends": ["airbnb", "prettier", "prettier/react"],
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"max-len": 0,
|
||||
"no-plusplus": 0,
|
||||
"no-bitwise" : 0,
|
||||
"no-bitwise": 0,
|
||||
"no-unused-expressions": 0,
|
||||
"prettier/prettier": 2,
|
||||
"react/destructuring-assignment": [0, "always"],
|
||||
"react/prop-types": 0,
|
||||
"react/no-deprecated": 0,
|
||||
@@ -35,9 +35,7 @@
|
||||
"aw": false,
|
||||
"page": false
|
||||
},
|
||||
"plugins": [
|
||||
"mocha"
|
||||
],
|
||||
"plugins": ["mocha"],
|
||||
"rules": {
|
||||
"mocha/no-exclusive-tests": "error"
|
||||
}
|
||||
|
||||
6
.prettierrc
Normal file
6
.prettierrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"endOfLine": "lf",
|
||||
"printWidth": 120,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
@@ -4,7 +4,8 @@
|
||||
"scripts": {
|
||||
"build": "cross-env NODE_ENV=production FORCE_COLOR=1 lerna run build --stream",
|
||||
"build:watch": "FORCE_COLOR=1 lerna run build:watch --stream --concurrency 99 --no-sort",
|
||||
"lint": "eslint packages --ext .js --ext .jsx",
|
||||
"lint": "eslint packages --ext .js,.jsx",
|
||||
"lint:check": "eslint --print-config ./aw.config.js | eslint-config-prettier-check",
|
||||
"start": "MONO=true ./packages/cli/lib/index.js serve --entry ./test/integration/sn.js",
|
||||
"test": "yarn run test:unit",
|
||||
"test:integration": "aw puppet -c aw.config.js --type integration",
|
||||
@@ -39,13 +40,16 @@
|
||||
"enigma.js": "^2.4.0",
|
||||
"eslint": "^6.1.0",
|
||||
"eslint-config-airbnb": "^18.0.1",
|
||||
"eslint-config-prettier": "^6.1.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"eslint-plugin-jsx-a11y": "^6.2.3",
|
||||
"eslint-plugin-mocha": "^6.0.0",
|
||||
"eslint-plugin-prettier": "^3.1.0",
|
||||
"eslint-plugin-react": "^7.14.3",
|
||||
"husky": "^3.0.3",
|
||||
"lerna": "^3.16.4",
|
||||
"lint-staged": "^9.2.1",
|
||||
"prettier": "^1.18.2",
|
||||
"rollup": "^1.19.4",
|
||||
"rollup-plugin-babel": "^4.3.3",
|
||||
"rollup-plugin-commonjs": "^10.0.2",
|
||||
|
||||
@@ -7,18 +7,9 @@ const replace = require('rollup-plugin-replace');
|
||||
const node = require('rollup-plugin-node-resolve');
|
||||
const { terser } = require('rollup-plugin-terser');
|
||||
|
||||
const config = ({
|
||||
mode = 'production',
|
||||
format = 'umd',
|
||||
cwd = process.cwd(),
|
||||
} = {}) => {
|
||||
const config = ({ mode = 'production', format = 'umd', cwd = process.cwd() } = {}) => {
|
||||
const pkg = require(path.resolve(cwd, 'package.json')); // eslint-disable-line
|
||||
const {
|
||||
name,
|
||||
version,
|
||||
license,
|
||||
author,
|
||||
} = pkg;
|
||||
const { name, version, license, author } = pkg;
|
||||
|
||||
const auth = typeof author === 'object' ? `${author.name} <${author.email}>` : author || '';
|
||||
const moduleName = name.split('/').reverse()[0];
|
||||
@@ -49,20 +40,27 @@ const config = ({
|
||||
babel({
|
||||
babelrc: false,
|
||||
presets: [
|
||||
['@babel/preset-env', {
|
||||
modules: false,
|
||||
targets: {
|
||||
browsers: ['ie 11', 'chrome 47'],
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
modules: false,
|
||||
targets: {
|
||||
browsers: ['ie 11', 'chrome 47'],
|
||||
},
|
||||
},
|
||||
}],
|
||||
],
|
||||
],
|
||||
}),
|
||||
postcss({}),
|
||||
...[mode === 'production' ? terser({
|
||||
output: {
|
||||
preamble: banner,
|
||||
},
|
||||
}) : false],
|
||||
...[
|
||||
mode === 'production'
|
||||
? terser({
|
||||
output: {
|
||||
preamble: banner,
|
||||
},
|
||||
})
|
||||
: false,
|
||||
],
|
||||
].filter(Boolean),
|
||||
},
|
||||
output: {
|
||||
@@ -108,7 +106,7 @@ const watch = async () => {
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
watcher.on('event', (event) => {
|
||||
watcher.on('event', event => {
|
||||
if (event.code === 'FATAL') {
|
||||
console.error(event);
|
||||
reject();
|
||||
|
||||
@@ -6,12 +6,12 @@ const create = require('@nebula.js/cli-create/command');
|
||||
const serve = require('@nebula.js/cli-serve/command');
|
||||
const sense = require('@nebula.js/cli-sense/command');
|
||||
|
||||
yargs.usage('nebula <command> [options]')
|
||||
yargs
|
||||
.usage('nebula <command> [options]')
|
||||
.command(build)
|
||||
.command(create)
|
||||
.command(serve)
|
||||
.command(sense)
|
||||
.demandCommand()
|
||||
.alias('h', 'help')
|
||||
.wrap(Math.min(80, yargs.terminalWidth()))
|
||||
.argv;
|
||||
.wrap(Math.min(80, yargs.terminalWidth())).argv;
|
||||
|
||||
@@ -18,10 +18,14 @@ const hasYarn = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const author = async (cwd) => {
|
||||
const author = async cwd => {
|
||||
try {
|
||||
const email = execSync('git config --get user.email', { cwd }).toString().trim();
|
||||
const name = execSync('git config --get user.name', { cwd }).toString().trim();
|
||||
const email = execSync('git config --get user.email', { cwd })
|
||||
.toString()
|
||||
.trim();
|
||||
const name = execSync('git config --get user.name', { cwd })
|
||||
.toString()
|
||||
.trim();
|
||||
return {
|
||||
email,
|
||||
name,
|
||||
@@ -54,7 +58,7 @@ function cpy(root, destination) {
|
||||
};
|
||||
}
|
||||
|
||||
const create = async (argv) => {
|
||||
const create = async argv => {
|
||||
const { name } = argv;
|
||||
|
||||
const projectFolder = name;
|
||||
@@ -67,8 +71,8 @@ const create = async (argv) => {
|
||||
let options = {
|
||||
install: true,
|
||||
...argv,
|
||||
pkgm: argv.pkgm || (await hasYarn() ? 'yarn' : 'npm'),
|
||||
author: argv.author ? parseAuthor(argv.author) : (await author()),
|
||||
pkgm: argv.pkgm || ((await hasYarn()) ? 'yarn' : 'npm'),
|
||||
author: argv.author ? parseAuthor(argv.author) : await author(),
|
||||
};
|
||||
|
||||
const results = {};
|
||||
@@ -79,14 +83,16 @@ const create = async (argv) => {
|
||||
}
|
||||
|
||||
const prompt = async () => {
|
||||
const answers = await inquirer.prompt([{
|
||||
type: 'list',
|
||||
name: 'picasso',
|
||||
message: 'Pick a picasso template',
|
||||
default: 'none',
|
||||
choices: ['none', 'minimal', 'barchart'],
|
||||
when: !argv.picasso,
|
||||
}]);
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
type: 'list',
|
||||
name: 'picasso',
|
||||
message: 'Pick a picasso template',
|
||||
default: 'none',
|
||||
choices: ['none', 'minimal', 'barchart'],
|
||||
when: !argv.picasso,
|
||||
},
|
||||
]);
|
||||
|
||||
options = { ...options, ...answers };
|
||||
};
|
||||
@@ -99,15 +105,12 @@ const create = async (argv) => {
|
||||
|
||||
// ==== common files ====
|
||||
// copy raw files
|
||||
[
|
||||
'editorconfig',
|
||||
'eslintignore',
|
||||
'gitignore',
|
||||
'eslintrc.json',
|
||||
].forEach((filename) => fs.copyFileSync(
|
||||
path.resolve(templatesRoot, 'common', `_${filename}`), // copying dotfiles may not always work, so they are prefixed with an underline
|
||||
path.resolve(destination, `.${filename}`),
|
||||
));
|
||||
['editorconfig', 'eslintignore', 'gitignore', 'eslintrc.json'].forEach(filename =>
|
||||
fs.copyFileSync(
|
||||
path.resolve(templatesRoot, 'common', `_${filename}`), // copying dotfiles may not always work, so they are prefixed with an underline
|
||||
path.resolve(destination, `.${filename}`)
|
||||
)
|
||||
);
|
||||
|
||||
const copy = cpy(templatesRoot, destination);
|
||||
|
||||
@@ -125,7 +128,7 @@ const create = async (argv) => {
|
||||
const traverse = (sourceFolder, targetFolder = '') => {
|
||||
const files = fs.readdirSync(path.resolve(templatesRoot, sourceFolder));
|
||||
|
||||
files.forEach((file) => {
|
||||
files.forEach(file => {
|
||||
const p = `${sourceFolder}/${file}`;
|
||||
const stats = fs.lstatSync(path.resolve(templatesRoot, p));
|
||||
const next = `${targetFolder}/${file}`.replace(/^\//, '');
|
||||
@@ -146,7 +149,7 @@ const create = async (argv) => {
|
||||
});
|
||||
};
|
||||
|
||||
folders.forEach((folder) => {
|
||||
folders.forEach(folder => {
|
||||
traverse(folder);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -14,10 +14,7 @@ export default function supernova(env) {
|
||||
mounted(element) {
|
||||
element.innerHTML = '<div>Hello!</div>'; // eslint-disable-line
|
||||
},
|
||||
render({
|
||||
layout,
|
||||
context,
|
||||
}) {
|
||||
render({ layout, context }) {
|
||||
console.log('render', layout, context);
|
||||
},
|
||||
resize() {},
|
||||
|
||||
@@ -4,7 +4,7 @@ describe('sn', () => {
|
||||
const app = encodeURIComponent(process.env.APP_ID || '/apps/ctrl00.qvf');
|
||||
await page.goto(`${process.testServer.url}/render/app/${app}`);
|
||||
await page.waitForFunction(`!!document.querySelector('${content}')`);
|
||||
const text = await page.$eval(content, (el) => el.textContent);
|
||||
const text = await page.$eval(content, el => el.textContent);
|
||||
expect(text).to.equal('Hello!');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ before(async () => {
|
||||
|
||||
process.testServer = s;
|
||||
|
||||
page.on('pageerror', (e) => {
|
||||
page.on('pageerror', e => {
|
||||
console.log('Error:', e.message, e.stack);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
export default {
|
||||
targets: [{
|
||||
path: 'qHyperCubeDef',
|
||||
dimensions: {
|
||||
min: 1,
|
||||
max: 1,
|
||||
targets: [
|
||||
{
|
||||
path: 'qHyperCubeDef',
|
||||
dimensions: {
|
||||
min: 1,
|
||||
max: 1,
|
||||
},
|
||||
measures: {
|
||||
min: 1,
|
||||
max: 1,
|
||||
},
|
||||
},
|
||||
measures: {
|
||||
min: 1,
|
||||
max: 1,
|
||||
},
|
||||
}],
|
||||
],
|
||||
};
|
||||
|
||||
@@ -2,9 +2,7 @@ const properties = {
|
||||
qHyperCubeDef: {
|
||||
qDimensions: [],
|
||||
qMeasures: [],
|
||||
qInitialDataFetch: [
|
||||
{ qWidth: 2, qHeight: 5000 },
|
||||
],
|
||||
qInitialDataFetch: [{ qWidth: 2, qHeight: 5000 }],
|
||||
qSuppressZero: false,
|
||||
qSuppressMissing: true,
|
||||
},
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
export default function picassoDefinition({
|
||||
layout,
|
||||
context,
|
||||
}) {
|
||||
export default function picassoDefinition({ layout, context }) {
|
||||
if (!layout.qHyperCube) {
|
||||
throw new Error('Layout is missing a hypercube');
|
||||
}
|
||||
@@ -15,46 +12,57 @@ export default function picassoDefinition({
|
||||
invert: true,
|
||||
},
|
||||
},
|
||||
components: [{
|
||||
type: 'axis',
|
||||
dock: 'left',
|
||||
scale: 'y',
|
||||
}, {
|
||||
type: 'axis',
|
||||
dock: 'bottom',
|
||||
scale: 'x',
|
||||
}, {
|
||||
type: 'box',
|
||||
data: {
|
||||
extract: {
|
||||
field: 'qDimensionInfo/0',
|
||||
props: {
|
||||
start: 0,
|
||||
end: { field: 'qMeasureInfo/0' },
|
||||
},
|
||||
},
|
||||
components: [
|
||||
{
|
||||
type: 'axis',
|
||||
dock: 'left',
|
||||
scale: 'y',
|
||||
},
|
||||
settings: {
|
||||
major: { scale: 'x' },
|
||||
minor: { scale: 'y' },
|
||||
box: {
|
||||
width: 0.7,
|
||||
},
|
||||
{
|
||||
type: 'axis',
|
||||
dock: 'bottom',
|
||||
scale: 'x',
|
||||
},
|
||||
brush: context.permissions.indexOf('interact') !== -1 && context.permissions.indexOf('select') !== -1 ? {
|
||||
trigger: [{
|
||||
contexts: ['selection'],
|
||||
}],
|
||||
consume: [{
|
||||
context: 'selection',
|
||||
data: ['', 'end'],
|
||||
style: {
|
||||
inactive: {
|
||||
opacity: 0.3,
|
||||
{
|
||||
type: 'box',
|
||||
data: {
|
||||
extract: {
|
||||
field: 'qDimensionInfo/0',
|
||||
props: {
|
||||
start: 0,
|
||||
end: { field: 'qMeasureInfo/0' },
|
||||
},
|
||||
},
|
||||
}],
|
||||
} : {},
|
||||
}],
|
||||
},
|
||||
settings: {
|
||||
major: { scale: 'x' },
|
||||
minor: { scale: 'y' },
|
||||
box: {
|
||||
width: 0.7,
|
||||
},
|
||||
},
|
||||
brush:
|
||||
context.permissions.indexOf('interact') !== -1 && context.permissions.indexOf('select') !== -1
|
||||
? {
|
||||
trigger: [
|
||||
{
|
||||
contexts: ['selection'],
|
||||
},
|
||||
],
|
||||
consume: [
|
||||
{
|
||||
context: 'selection',
|
||||
data: ['', 'end'],
|
||||
style: {
|
||||
inactive: {
|
||||
opacity: 0.3,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
: {},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,14 +2,16 @@ describe('interaction', () => {
|
||||
const content = '.nebulajs-sn';
|
||||
it('should select two bars', async () => {
|
||||
const app = encodeURIComponent(process.env.APP_ID || '/apps/ctrl00.qvf');
|
||||
await page.goto(`${process.testServer.url}/render/app/${app}?cols=Alpha,=5+avg(Expression1)&&permissions=interact,select`);
|
||||
await page.goto(
|
||||
`${process.testServer.url}/render/app/${app}?cols=Alpha,=5+avg(Expression1)&&permissions=interact,select`
|
||||
);
|
||||
await page.waitForFunction(`!!document.querySelector('${content}')`);
|
||||
|
||||
await page.click('rect[data-label="K"]');
|
||||
await page.click('rect[data-label="S"]');
|
||||
await page.click('button[title="Confirm selection"]');
|
||||
|
||||
const rects = await page.$$eval('rect[data-label]', (sel) => sel.map((r) => r.getAttribute('data-label')));
|
||||
const rects = await page.$$eval('rect[data-label]', sel => sel.map(r => r.getAttribute('data-label')));
|
||||
expect(rects).to.eql(['K', 'S']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,16 +29,15 @@ export default function supernova(/* env */) {
|
||||
picassoQ,
|
||||
});
|
||||
},
|
||||
render({
|
||||
layout,
|
||||
context,
|
||||
}) {
|
||||
render({ layout, context }) {
|
||||
this.pic.update({
|
||||
data: [{
|
||||
type: 'q',
|
||||
key: 'qHyperCube',
|
||||
data: layout.qHyperCube,
|
||||
}],
|
||||
data: [
|
||||
{
|
||||
type: 'q',
|
||||
key: 'qHyperCube',
|
||||
data: layout.qHyperCube,
|
||||
},
|
||||
],
|
||||
settings: definition({ layout, context }),
|
||||
});
|
||||
},
|
||||
|
||||
@@ -11,15 +11,15 @@ const KEYS = {
|
||||
|
||||
const instances = [];
|
||||
let expando = 0;
|
||||
const confirmOrCancelSelection = (e) => {
|
||||
const active = instances.filter((a) => a.selections && a.selections.isActive());
|
||||
const confirmOrCancelSelection = e => {
|
||||
const active = instances.filter(a => a.selections && a.selections.isActive());
|
||||
if (!active.length) {
|
||||
return;
|
||||
}
|
||||
if (e.key === KEYS.ENTER) {
|
||||
active.forEach((a) => a.selections.confirm());
|
||||
active.forEach(a => a.selections.confirm());
|
||||
} else if (e.key === KEYS.ESCAPE || e.key === KEYS.IE11_ESC) {
|
||||
active.forEach((a) => a.selections.cancel());
|
||||
active.forEach(a => a.selections.cancel());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,24 +33,18 @@ const teardown = () => {
|
||||
// ------------------------------------------------------
|
||||
|
||||
const addListeners = (emitter, listeners) => {
|
||||
Object.keys(listeners).forEach((type) => {
|
||||
Object.keys(listeners).forEach(type => {
|
||||
emitter.on(type, listeners[type]);
|
||||
});
|
||||
};
|
||||
|
||||
const removeListeners = (emitter, listeners) => {
|
||||
Object.keys(listeners).forEach((type) => {
|
||||
Object.keys(listeners).forEach(type => {
|
||||
emitter.removeListener(type, listeners[type]);
|
||||
});
|
||||
};
|
||||
|
||||
export default function ({
|
||||
selections,
|
||||
brush,
|
||||
picassoQ,
|
||||
} = {}, {
|
||||
path = '/qHyperCubeDef',
|
||||
} = {}) {
|
||||
export default function({ selections, brush, picassoQ } = {}, { path = '/qHyperCubeDef' } = {}) {
|
||||
if (!selections) {
|
||||
return {
|
||||
release: () => {},
|
||||
@@ -61,21 +55,24 @@ export default function ({
|
||||
let layout = null;
|
||||
|
||||
// interceptors primary job is to ensure selections only occur on either values OR ranges
|
||||
const valueInterceptor = (added) => {
|
||||
const valueInterceptor = added => {
|
||||
const brushes = brush.brushes();
|
||||
brushes.forEach((b) => {
|
||||
if (b.type === 'range') { // has range selections
|
||||
brushes.forEach(b => {
|
||||
if (b.type === 'range') {
|
||||
// has range selections
|
||||
brush.clear([]);
|
||||
} else if (added[0] && added[0].key !== b.id) { // has selections in another dimension
|
||||
} else if (added[0] && added[0].key !== b.id) {
|
||||
// has selections in another dimension
|
||||
brush.clear([]);
|
||||
}
|
||||
});
|
||||
return added.filter((t) => t.value !== -2); // do not allow selection on null value
|
||||
return added.filter(t => t.value !== -2); // do not allow selection on null value
|
||||
};
|
||||
|
||||
const rangeInterceptor = (a) => {
|
||||
const v = brush.brushes().filter((b) => b.type === 'value');
|
||||
if (v.length) { // has dimension values selected
|
||||
const rangeInterceptor = a => {
|
||||
const v = brush.brushes().filter(b => b.type === 'value');
|
||||
if (v.length) {
|
||||
// has dimension values selected
|
||||
brush.clear([]);
|
||||
return a;
|
||||
}
|
||||
@@ -103,7 +100,7 @@ export default function ({
|
||||
|
||||
brush.on('update', () => {
|
||||
const generated = picassoQ.selections(brush, {}, layout);
|
||||
generated.forEach((s) => selections.select(s));
|
||||
generated.forEach(s => selections.select(s));
|
||||
});
|
||||
|
||||
if (instances.length === 0) {
|
||||
@@ -116,10 +113,12 @@ export default function ({
|
||||
});
|
||||
|
||||
return {
|
||||
layout: (lt) => { layout = lt; },
|
||||
layout: lt => {
|
||||
layout = lt;
|
||||
},
|
||||
release: () => {
|
||||
layout = null;
|
||||
const idx = instances.indexOf(instances.filter((i) => i.key === key)[0]);
|
||||
const idx = instances.indexOf(instances.filter(i => i.key === key)[0]);
|
||||
if (idx !== -1) {
|
||||
instances.splice(idx, 1);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ before(async () => {
|
||||
|
||||
process.testServer = s;
|
||||
|
||||
page.on('pageerror', (e) => {
|
||||
page.on('pageerror', e => {
|
||||
console.log('Error:', e.message, e.stack);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
export default {
|
||||
targets: [{
|
||||
path: 'qHyperCubeDef',
|
||||
dimensions: {
|
||||
min: 1,
|
||||
targets: [
|
||||
{
|
||||
path: 'qHyperCubeDef',
|
||||
dimensions: {
|
||||
min: 1,
|
||||
},
|
||||
measures: {
|
||||
min: 1,
|
||||
},
|
||||
},
|
||||
measures: {
|
||||
min: 1,
|
||||
},
|
||||
}],
|
||||
],
|
||||
};
|
||||
|
||||
@@ -2,9 +2,7 @@ const properties = {
|
||||
qHyperCubeDef: {
|
||||
qDimensions: [],
|
||||
qMeasures: [],
|
||||
qInitialDataFetch: [
|
||||
{ qWidth: 10, qHeight: 500 },
|
||||
],
|
||||
qInitialDataFetch: [{ qWidth: 10, qHeight: 500 }],
|
||||
qSuppressZero: false,
|
||||
qSuppressMissing: true,
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default function ({
|
||||
export default function({
|
||||
layout, // eslint-disable-line no-unused-vars
|
||||
context, // eslint-disable-line no-unused-vars
|
||||
}) {
|
||||
|
||||
@@ -10,10 +10,11 @@ const mock = ({
|
||||
Typography: ({ children }) => <t>{children}</t>,
|
||||
},
|
||||
STB = () => <stb />,
|
||||
} = {}) => aw.mock([
|
||||
['**/ui/components/index.js', () => components],
|
||||
['**/SelectionToolbar.jsx', () => STB],
|
||||
], ['../../src/components/Header']);
|
||||
} = {}) =>
|
||||
aw.mock(
|
||||
[['**/ui/components/index.js', () => components], ['**/SelectionToolbar.jsx', () => STB]],
|
||||
['../../src/components/Header']
|
||||
);
|
||||
|
||||
describe('<Header />', () => {
|
||||
it('should render a title', () => {
|
||||
@@ -21,13 +22,28 @@ describe('<Header />', () => {
|
||||
const [{ default: Header }] = mock();
|
||||
const tree = renderer.create(<Header layout={layout} />).toJSON();
|
||||
expect(tree).to.eql({
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 't', props: {}, children: ['title'],
|
||||
}],
|
||||
}],
|
||||
}, { type: 'g', props: {}, children: null }],
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 't',
|
||||
props: {},
|
||||
children: ['title'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{ type: 'g', props: {}, children: null },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -36,13 +52,28 @@ describe('<Header />', () => {
|
||||
const [{ default: Header }] = mock();
|
||||
const tree = renderer.create(<Header layout={layout} />).toJSON();
|
||||
expect(tree).to.eql({
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 't', props: {}, children: ['sub'],
|
||||
}],
|
||||
}],
|
||||
}, { type: 'g', props: {}, children: null }],
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 't',
|
||||
props: {},
|
||||
children: ['sub'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{ type: 'g', props: {}, children: null },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,13 +82,32 @@ describe('<Header />', () => {
|
||||
const [{ default: Header }] = mock();
|
||||
const tree = renderer.create(<Header layout={layout} sn />).toJSON();
|
||||
expect(tree).to.eql({
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 'g', props: {}, children: null,
|
||||
}],
|
||||
}, { type: 'g', props: {}, children: [{
|
||||
type: 'stb', props: {}, children: null,
|
||||
}] }],
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'stb',
|
||||
props: {},
|
||||
children: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
|
||||
describe('ObjectAPI', () => {
|
||||
const doMock = ({
|
||||
createObjectSelectionAPI = () => ({}),
|
||||
} = {}) => aw.mock([
|
||||
['**/selections/index.js', () => ({
|
||||
createObjectSelectionAPI,
|
||||
})],
|
||||
], ['../../src/object/object-api']);
|
||||
const doMock = ({ createObjectSelectionAPI = () => ({}) } = {}) =>
|
||||
aw.mock(
|
||||
[
|
||||
[
|
||||
'**/selections/index.js',
|
||||
() => ({
|
||||
createObjectSelectionAPI,
|
||||
}),
|
||||
],
|
||||
],
|
||||
['../../src/object/object-api']
|
||||
);
|
||||
|
||||
it('setState should pass props to viz', () => {
|
||||
const [{ default: API }] = doMock();
|
||||
@@ -75,7 +79,9 @@ describe('ObjectAPI', () => {
|
||||
},
|
||||
config: { env: { Promise: { resolve: sinon.spy() } } },
|
||||
};
|
||||
context.nebbie.types.get.withArgs({ name: 'my-type', version: 'my-sn-version' }).returns({ supernova: () => Promise.resolve('my-sn') });
|
||||
context.nebbie.types.get
|
||||
.withArgs({ name: 'my-type', version: 'my-sn-version' })
|
||||
.returns({ supernova: () => Promise.resolve('my-sn') });
|
||||
api = new API('model', context, 'viz');
|
||||
api.setSupernova = sinon.spy();
|
||||
});
|
||||
@@ -136,7 +142,11 @@ describe('ObjectAPI', () => {
|
||||
api.setType = sinon.spy();
|
||||
api.setState = sinon.spy();
|
||||
api.setLayout({ visualization: 'viz', version: 'prop-version' });
|
||||
expect(api.setState).to.have.been.calledWithExactly({ layout: { visualization: 'viz', version: 'prop-version' }, error: null, sn: null });
|
||||
expect(api.setState).to.have.been.calledWithExactly({
|
||||
layout: { visualization: 'viz', version: 'prop-version' },
|
||||
error: null,
|
||||
sn: null,
|
||||
});
|
||||
expect(api.setType).to.have.been.calledWithExactly('viz', 'prop-version', 'sn-version');
|
||||
});
|
||||
|
||||
@@ -147,7 +157,10 @@ describe('ObjectAPI', () => {
|
||||
api.currentObjectType = 'viz';
|
||||
api.currentPropertyVersion = '1.0.0';
|
||||
api.setLayout({ visualization: 'viz', version: '1.0.0' });
|
||||
expect(api.setState).to.have.been.calledWithExactly({ layout: { visualization: 'viz', version: '1.0.0' }, error: null });
|
||||
expect(api.setState).to.have.been.calledWithExactly({
|
||||
layout: { visualization: 'viz', version: '1.0.0' },
|
||||
error: null,
|
||||
});
|
||||
expect(api.setType).to.not.have.been.called;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,10 +25,10 @@ describe('<SelectionToolbar />', () => {
|
||||
};
|
||||
const STItem = () => '';
|
||||
const LocaleContext = React.createContext();
|
||||
const [{ default: STB }] = aw.mock([
|
||||
['**/SelectionToolbarItem.jsx', () => STItem],
|
||||
['**/LocaleContext.js', () => LocaleContext],
|
||||
], ['../../src/components/SelectionToolbar']);
|
||||
const [{ default: STB }] = aw.mock(
|
||||
[['**/SelectionToolbarItem.jsx', () => STItem], ['**/LocaleContext.js', () => LocaleContext]],
|
||||
['../../src/components/SelectionToolbar']
|
||||
);
|
||||
|
||||
const translator = {
|
||||
get: sinon.stub(),
|
||||
@@ -41,7 +41,7 @@ describe('<SelectionToolbar />', () => {
|
||||
const c = renderer.create(
|
||||
<LocaleContext.Provider value={translator}>
|
||||
<STB sn={props.sn} />
|
||||
</LocaleContext.Provider>,
|
||||
</LocaleContext.Provider>
|
||||
);
|
||||
|
||||
items = c.root.findAllByType(STItem);
|
||||
@@ -112,10 +112,10 @@ describe('<SelectionToolbar />', () => {
|
||||
};
|
||||
const STItem = ({ isCustom }) => `-${isCustom}-`;
|
||||
const LocaleContext = React.createContext();
|
||||
const [{ default: STB }] = aw.mock([
|
||||
['**/SelectionToolbarItem.jsx', () => STItem],
|
||||
['**/LocaleContext.js', () => LocaleContext],
|
||||
], ['../../src/components/SelectionToolbar']);
|
||||
const [{ default: STB }] = aw.mock(
|
||||
[['**/SelectionToolbarItem.jsx', () => STItem], ['**/LocaleContext.js', () => LocaleContext]],
|
||||
['../../src/components/SelectionToolbar']
|
||||
);
|
||||
|
||||
const translator = {
|
||||
get: sinon.stub(),
|
||||
@@ -124,7 +124,7 @@ describe('<SelectionToolbar />', () => {
|
||||
const c = renderer.create(
|
||||
<LocaleContext.Provider value={translator}>
|
||||
<STB sn={props.sn} />
|
||||
</LocaleContext.Provider>,
|
||||
</LocaleContext.Provider>
|
||||
);
|
||||
|
||||
expect(c.toJSON()).to.eql({
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
const flush = () => new Promise((r) => setImmediate(r));
|
||||
const flush = () => new Promise(r => setImmediate(r));
|
||||
|
||||
describe('viz', () => {
|
||||
const doMock = ({
|
||||
boot = () => {},
|
||||
getter = () => {},
|
||||
getPatches = () => {},
|
||||
} = {}) => aw.mock([
|
||||
['**/components/boot.jsx', () => boot],
|
||||
['**/object/observer.js', () => ({ get: getter })],
|
||||
['**/utils/patcher.js', () => getPatches],
|
||||
], ['../viz.js']);
|
||||
const doMock = ({ boot = () => {}, getter = () => {}, getPatches = () => {} } = {}) =>
|
||||
aw.mock(
|
||||
[
|
||||
['**/components/boot.jsx', () => boot],
|
||||
['**/object/observer.js', () => ({ get: getter })],
|
||||
['**/utils/patcher.js', () => getPatches],
|
||||
],
|
||||
['../viz.js']
|
||||
);
|
||||
|
||||
describe('api', () => {
|
||||
let api;
|
||||
@@ -77,7 +77,9 @@ describe('viz', () => {
|
||||
|
||||
let mounted = false;
|
||||
|
||||
api.mount('element').then(() => { mounted = true; });
|
||||
api.mount('element').then(() => {
|
||||
mounted = true;
|
||||
});
|
||||
setObjectProps({ layout: {}, sn: {} });
|
||||
|
||||
await flush();
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import React, {
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import {
|
||||
Grid,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { Grid } from '@nebula.js/ui/components';
|
||||
|
||||
import Requirements from './Requirements';
|
||||
import CError from './Error';
|
||||
@@ -24,8 +19,7 @@ const showRequirements = (sn, layout) => {
|
||||
}
|
||||
const minD = def.dimensions.min();
|
||||
const minM = def.measures.min();
|
||||
return (layout.qHyperCube.qDimensionInfo.length < minD
|
||||
|| layout.qHyperCube.qMeasureInfo.length < minM);
|
||||
return layout.qHyperCube.qDimensionInfo.length < minD || layout.qHyperCube.qMeasureInfo.length < minM;
|
||||
};
|
||||
|
||||
const Content = ({ children }) => (
|
||||
@@ -45,10 +39,7 @@ const Content = ({ children }) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
export default function Cell({
|
||||
api,
|
||||
onInitial,
|
||||
}) {
|
||||
export default function Cell({ api, onInitial }) {
|
||||
const [, setChanged] = useState(0);
|
||||
useEffect(() => {
|
||||
const onChanged = () => setChanged(Date.now());
|
||||
@@ -65,27 +56,29 @@ export default function Cell({
|
||||
const objectProps = api.objectProps();
|
||||
const userProps = api.userProps();
|
||||
|
||||
const SN = (showRequirements(objectProps.sn, objectProps.layout) ? Requirements : Supernova);
|
||||
const SN = showRequirements(objectProps.sn, objectProps.layout) ? Requirements : Supernova;
|
||||
const Comp = !objectProps.sn ? Placeholder : SN;
|
||||
const err = objectProps.error || false;
|
||||
return (
|
||||
<Grid container direction="column" spacing={0} style={{ height: '100%', padding: '8px', boxSixing: 'borderBox' }}>
|
||||
<Grid item style={{ maxWidth: '100%' }}>
|
||||
<Header layout={objectProps.layout} sn={objectProps.sn}> </Header>
|
||||
<Header layout={objectProps.layout} sn={objectProps.sn}>
|
||||
|
||||
</Header>
|
||||
</Grid>
|
||||
<Grid item xs>
|
||||
<Content>
|
||||
{err
|
||||
? (<CError message={err.message} />)
|
||||
: (
|
||||
<Comp
|
||||
key={objectProps.layout.visualization}
|
||||
sn={objectProps.sn}
|
||||
snContext={userProps.context}
|
||||
snOptions={userProps.options}
|
||||
layout={objectProps.layout}
|
||||
/>
|
||||
)}
|
||||
{err ? (
|
||||
<CError message={err.message} />
|
||||
) : (
|
||||
<Comp
|
||||
key={objectProps.layout.visualization}
|
||||
sn={objectProps.sn}
|
||||
snContext={userProps.context}
|
||||
snOptions={userProps.options}
|
||||
layout={objectProps.layout}
|
||||
/>
|
||||
)}
|
||||
</Content>
|
||||
</Grid>
|
||||
<Footer layout={objectProps.layout} />
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
|
||||
import { prefixer } from '../utils/utils';
|
||||
|
||||
const Component = (props) => (
|
||||
const Component = props => (
|
||||
<div className={prefixer('cell__error')}>
|
||||
<div>Error</div>
|
||||
<div>{props.message}</div>
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
Typography,
|
||||
Grid,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { Typography, Grid } from '@nebula.js/ui/components';
|
||||
|
||||
const Footer = ({ layout }) => (
|
||||
const Footer = ({ layout }) =>
|
||||
layout && layout.showTitles && layout.footnote ? (
|
||||
<Grid container>
|
||||
<Grid item style={{ minWidth: 0 }}>
|
||||
<Typography noWrap variant="body2">{layout.footnote}</Typography>
|
||||
<Typography noWrap variant="body2">
|
||||
{layout.footnote}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
) : null
|
||||
);
|
||||
) : null;
|
||||
|
||||
export default Footer;
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
Grid,
|
||||
Typography,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { Grid, Typography } from '@nebula.js/ui/components';
|
||||
|
||||
import SelectionToolbar from './SelectionToolbar';
|
||||
|
||||
const Header = ({
|
||||
layout,
|
||||
sn,
|
||||
}) => {
|
||||
const Header = ({ layout, sn }) => {
|
||||
const showTitle = layout && layout.showTitles && !!layout.title;
|
||||
const showSubtitle = layout && layout.showTitles && !!layout.subtitle;
|
||||
const showInSelectionActions = sn && layout && layout.qSelectionInfo && layout.qSelectionInfo.qInSelections;
|
||||
@@ -18,12 +12,20 @@ const Header = ({
|
||||
<Grid container wrap="nowrap" style={{ flexGrow: 0 }}>
|
||||
<Grid item zeroMinWidth xs>
|
||||
<Grid container wrap="nowrap" direction="column">
|
||||
{showTitle && (<Typography variant="h6" noWrap>{layout.title}</Typography>)}
|
||||
{showSubtitle && (<Typography variant="body2" noWrap>{layout.subtitle}</Typography>)}
|
||||
{showTitle && (
|
||||
<Typography variant="h6" noWrap>
|
||||
{layout.title}
|
||||
</Typography>
|
||||
)}
|
||||
{showSubtitle && (
|
||||
<Typography variant="body2" noWrap>
|
||||
{layout.subtitle}
|
||||
</Typography>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item style={{ whiteSpace: 'nowrap', minHeight: '32px' }}>
|
||||
{showInSelectionActions && (<SelectionToolbar inline sn={sn} />)}
|
||||
{showInSelectionActions && <SelectionToolbar inline sn={sn} />}
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
import React, {
|
||||
useMemo,
|
||||
} from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import {
|
||||
createTheme,
|
||||
ThemeProvider,
|
||||
StylesProvider,
|
||||
createGenerateClassName,
|
||||
} from '@nebula.js/ui/theme';
|
||||
import { createTheme, ThemeProvider, StylesProvider, createGenerateClassName } from '@nebula.js/ui/theme';
|
||||
|
||||
import LocaleContext from '../contexts/LocaleContext';
|
||||
|
||||
@@ -16,38 +9,31 @@ const THEME_PREFIX = (process.env.NEBULA_VERSION || '').replace(/[.-]/g, '_');
|
||||
|
||||
let counter = 0;
|
||||
|
||||
function NebulaApp({
|
||||
children,
|
||||
themeName,
|
||||
translator,
|
||||
}) {
|
||||
const { theme, generator } = useMemo(() => ({
|
||||
theme: createTheme(themeName),
|
||||
generator: createGenerateClassName({
|
||||
productionPrefix: `${THEME_PREFIX}-`,
|
||||
disableGlobal: true,
|
||||
seed: `nebulajs-${counter++}`,
|
||||
function NebulaApp({ children, themeName, translator }) {
|
||||
const { theme, generator } = useMemo(
|
||||
() => ({
|
||||
theme: createTheme(themeName),
|
||||
generator: createGenerateClassName({
|
||||
productionPrefix: `${THEME_PREFIX}-`,
|
||||
disableGlobal: true,
|
||||
seed: `nebulajs-${counter++}`,
|
||||
}),
|
||||
}),
|
||||
}), [themeName]);
|
||||
[themeName]
|
||||
);
|
||||
|
||||
return (
|
||||
<StylesProvider generateClassName={generator}>
|
||||
<ThemeProvider theme={theme}>
|
||||
<LocaleContext.Provider value={translator}>
|
||||
<>
|
||||
{children}
|
||||
</>
|
||||
<>{children}</>
|
||||
</LocaleContext.Provider>
|
||||
</ThemeProvider>
|
||||
</StylesProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default function boot({
|
||||
app,
|
||||
theme = 'light',
|
||||
translator,
|
||||
}) {
|
||||
export default function boot({ app, theme = 'light', translator }) {
|
||||
const element = document.createElement('div');
|
||||
element.style.display = 'none';
|
||||
element.setAttribute('data-nebulajs-version', process.env.NEBULA_VERSION || '');
|
||||
@@ -58,14 +44,10 @@ export default function boot({
|
||||
|
||||
const update = () => {
|
||||
ReactDOM.render(
|
||||
<NebulaApp
|
||||
themeName={themeName}
|
||||
app={app}
|
||||
translator={translator}
|
||||
>
|
||||
<NebulaApp themeName={themeName} app={app} translator={translator}>
|
||||
{components}
|
||||
</NebulaApp>,
|
||||
element,
|
||||
element
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
const Component = () => (
|
||||
<div> </div>
|
||||
);
|
||||
const Component = () => <div> </div>;
|
||||
|
||||
export default Component;
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import {
|
||||
Typography,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { Typography } from '@nebula.js/ui/components';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const Component = () => (
|
||||
<Typography>More data required</Typography>
|
||||
);
|
||||
const Component = () => <Typography>More data required</Typography>;
|
||||
|
||||
export default Component;
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import React, {
|
||||
useContext,
|
||||
useMemo,
|
||||
} from 'react';
|
||||
import React, { useContext, useMemo } from 'react';
|
||||
|
||||
import Item from './SelectionToolbarItem';
|
||||
import LocaleContext from '../contexts/LocaleContext';
|
||||
|
||||
function Component({
|
||||
sn,
|
||||
}) {
|
||||
function Component({ sn }) {
|
||||
const translator = useContext(LocaleContext);
|
||||
const api = sn.component.selections;
|
||||
|
||||
@@ -19,30 +14,34 @@ function Component({
|
||||
};
|
||||
|
||||
const { items, custom } = useMemo(() => {
|
||||
const arr = [{
|
||||
key: 'confirm',
|
||||
type: 'icon-button',
|
||||
label: translator.get('Selection.Confirm'),
|
||||
icon: 'tick',
|
||||
enabled: () => s.confirmable,
|
||||
action: () => api.confirm(sn.component),
|
||||
}, {
|
||||
key: 'cancel',
|
||||
type: 'icon-button',
|
||||
label: translator.get('Selection.Cancel'),
|
||||
icon: 'close',
|
||||
enabled: () => s.cancelable,
|
||||
action: () => api.cancel(sn.component),
|
||||
}, {
|
||||
key: 'clear',
|
||||
type: 'icon-button',
|
||||
label: translator.get('Selection.Clear'),
|
||||
icon: 'clear-selections',
|
||||
enabled: () => s.clearable,
|
||||
action: () => api.clear(sn.component),
|
||||
}];
|
||||
const arr = [
|
||||
{
|
||||
key: 'confirm',
|
||||
type: 'icon-button',
|
||||
label: translator.get('Selection.Confirm'),
|
||||
icon: 'tick',
|
||||
enabled: () => s.confirmable,
|
||||
action: () => api.confirm(sn.component),
|
||||
},
|
||||
{
|
||||
key: 'cancel',
|
||||
type: 'icon-button',
|
||||
label: translator.get('Selection.Cancel'),
|
||||
icon: 'close',
|
||||
enabled: () => s.cancelable,
|
||||
action: () => api.cancel(sn.component),
|
||||
},
|
||||
{
|
||||
key: 'clear',
|
||||
type: 'icon-button',
|
||||
label: translator.get('Selection.Clear'),
|
||||
icon: 'clear-selections',
|
||||
enabled: () => s.clearable,
|
||||
action: () => api.clear(sn.component),
|
||||
},
|
||||
];
|
||||
const c = {};
|
||||
(sn.selectionToolbar.items || []).forEach((item) => {
|
||||
(sn.selectionToolbar.items || []).forEach(item => {
|
||||
c[item.key] = true;
|
||||
arr.push(item);
|
||||
});
|
||||
@@ -52,7 +51,9 @@ function Component({
|
||||
|
||||
return (
|
||||
<div>
|
||||
{items.map((itm) => <Item key={itm.key} item={itm} isCustom={!!custom[itm.key]} />)}
|
||||
{items.map(itm => (
|
||||
<Item key={itm.key} item={itm} isCustom={!!custom[itm.key]} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
IconButton,
|
||||
Button,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { IconButton, Button } from '@nebula.js/ui/components';
|
||||
|
||||
import CloseIcon from '@nebula.js/ui/icons/Close';
|
||||
import TickIcon from '@nebula.js/ui/icons/Tick';
|
||||
@@ -64,11 +61,7 @@ export default class Item extends React.Component {
|
||||
{Icon && <Icon />}
|
||||
</Button>
|
||||
) : (
|
||||
<IconButton
|
||||
title={item.label}
|
||||
onClick={() => item.action()}
|
||||
disabled={this.state.disabled}
|
||||
>
|
||||
<IconButton title={item.label} onClick={() => item.action()} disabled={this.state.disabled}>
|
||||
{Icon && <Icon />}
|
||||
</IconButton>
|
||||
);
|
||||
|
||||
@@ -24,10 +24,13 @@ const scheduleRender = (props, prev, initial, contentElement) => {
|
||||
}
|
||||
const prom = {};
|
||||
|
||||
const p = new Promise((resolve) => {
|
||||
const p = new Promise(resolve => {
|
||||
const timeout = setTimeout(() => {
|
||||
const parentRect = contentElement.parentElement.parentElement.getBoundingClientRect();
|
||||
const r = typeof props.snContext.logicalSize === 'function' ? props.snContext.logicalSize(props.layout, props.sn) : props.sn.logicalSize({ layout: props.layout });
|
||||
const r =
|
||||
typeof props.snContext.logicalSize === 'function'
|
||||
? props.snContext.logicalSize(props.layout, props.sn)
|
||||
: props.sn.logicalSize({ layout: props.layout });
|
||||
const logicalSize = r || undefined;
|
||||
if (r) {
|
||||
// const rect = that.element.getBoundingClientRect();
|
||||
@@ -40,7 +43,8 @@ const scheduleRender = (props, prev, initial, contentElement) => {
|
||||
let left = 0;
|
||||
let top = 0;
|
||||
|
||||
if (parentRatio > rRatio) { // parent is wider -> limit height
|
||||
if (parentRatio > rRatio) {
|
||||
// parent is wider -> limit height
|
||||
({ height } = parentRect);
|
||||
width = height * rRatio;
|
||||
left = (parentRect.width - width) / 2;
|
||||
@@ -53,7 +57,10 @@ const scheduleRender = (props, prev, initial, contentElement) => {
|
||||
}
|
||||
|
||||
constrainElement(contentElement, {
|
||||
top, left, width, height,
|
||||
top,
|
||||
left,
|
||||
width,
|
||||
height,
|
||||
});
|
||||
} else {
|
||||
constrainElement(contentElement);
|
||||
@@ -61,20 +68,24 @@ const scheduleRender = (props, prev, initial, contentElement) => {
|
||||
|
||||
initial.mount();
|
||||
|
||||
Promise.resolve(props.sn.component.render({
|
||||
layout: props.layout,
|
||||
options: props.snOptions || {},
|
||||
context: {
|
||||
permissions: (props.snContext || {}).permissions,
|
||||
theme: (props.snContext || {}).theme,
|
||||
rtl: (props.snContext || {}).rtl,
|
||||
localeInfo: (props.snContext || {}).localeInfo,
|
||||
logicalSize,
|
||||
},
|
||||
})).then(() => {
|
||||
initial.rendered();
|
||||
// props.sn.component.didUpdate(); // TODO - should check if component is in update stage
|
||||
}).then(resolve);
|
||||
Promise.resolve(
|
||||
props.sn.component.render({
|
||||
layout: props.layout,
|
||||
options: props.snOptions || {},
|
||||
context: {
|
||||
permissions: (props.snContext || {}).permissions,
|
||||
theme: (props.snContext || {}).theme,
|
||||
rtl: (props.snContext || {}).rtl,
|
||||
localeInfo: (props.snContext || {}).localeInfo,
|
||||
logicalSize,
|
||||
},
|
||||
})
|
||||
)
|
||||
.then(() => {
|
||||
initial.rendered();
|
||||
// props.sn.component.didUpdate(); // TODO - should check if component is in update stage
|
||||
})
|
||||
.then(resolve);
|
||||
}, 0);
|
||||
|
||||
prom.reject = () => {
|
||||
@@ -137,19 +148,23 @@ class Supernova extends React.Component {
|
||||
}
|
||||
};
|
||||
|
||||
this.next = scheduleRender({
|
||||
snOptions: this.props.snOptions,
|
||||
snContext: this.props.snContext,
|
||||
sn: this.props.sn,
|
||||
layout: this.props.layout,
|
||||
}, this.next, this.initial, this.contentElement);
|
||||
this.next = scheduleRender(
|
||||
{
|
||||
snOptions: this.props.snOptions,
|
||||
snContext: this.props.snContext,
|
||||
sn: this.props.sn,
|
||||
layout: this.props.layout,
|
||||
},
|
||||
this.next,
|
||||
this.initial,
|
||||
this.contentElement
|
||||
);
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const update = nextProps.sn
|
||||
&& !(nextProps.layout
|
||||
&& nextProps.layout.qSelectionInfo
|
||||
&& nextProps.layout.qSelectionInfo.qInSelections);
|
||||
const update =
|
||||
nextProps.sn &&
|
||||
!(nextProps.layout && nextProps.layout.qSelectionInfo && nextProps.layout.qSelectionInfo.qInSelections);
|
||||
if (!update) {
|
||||
return false;
|
||||
}
|
||||
@@ -183,16 +198,19 @@ class Supernova extends React.Component {
|
||||
return (
|
||||
<div
|
||||
style={style}
|
||||
ref={(element) => { this.element = element; }}
|
||||
ref={element => {
|
||||
this.element = element;
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
}}
|
||||
ref={(element) => { this.contentElement = element; }}
|
||||
ref={element => {
|
||||
this.contentElement = element;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,25 +2,10 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Cell from './Cell';
|
||||
|
||||
export default function boot({
|
||||
element,
|
||||
model,
|
||||
api,
|
||||
nebulaContext,
|
||||
onInitial,
|
||||
}) {
|
||||
const {
|
||||
root,
|
||||
} = nebulaContext;
|
||||
export default function boot({ element, model, api, nebulaContext, onInitial }) {
|
||||
const { root } = nebulaContext;
|
||||
|
||||
const portal = ReactDOM.createPortal(
|
||||
<Cell
|
||||
api={api}
|
||||
model={model}
|
||||
onInitial={onInitial}
|
||||
/>,
|
||||
element,
|
||||
);
|
||||
const portal = ReactDOM.createPortal(<Cell api={api} model={model} onInitial={onInitial} />, element);
|
||||
|
||||
const unmount = () => {
|
||||
root.remove(portal);
|
||||
|
||||
@@ -15,9 +15,7 @@ import useLayout from '../../hooks/useLayout';
|
||||
|
||||
import Row from './ListBoxRow';
|
||||
|
||||
export default function ListBox({
|
||||
model,
|
||||
}) {
|
||||
export default function ListBox({ model }) {
|
||||
const [layout] = useLayout(model);
|
||||
const [pages, setPages] = useState(null);
|
||||
const loaderRef = useRef(null);
|
||||
@@ -30,51 +28,68 @@ export default function ListBox({
|
||||
pages: [],
|
||||
});
|
||||
|
||||
const onClick = useCallback((e) => {
|
||||
const elemNumber = +e.currentTarget.getAttribute('data-n');
|
||||
if (!Number.isNaN(elemNumber)) {
|
||||
model.selectListObjectValues('/qListObjectDef', [elemNumber], true);
|
||||
}
|
||||
}, [model]);
|
||||
const onClick = useCallback(
|
||||
e => {
|
||||
const elemNumber = +e.currentTarget.getAttribute('data-n');
|
||||
if (!Number.isNaN(elemNumber)) {
|
||||
model.selectListObjectValues('/qListObjectDef', [elemNumber], true);
|
||||
}
|
||||
},
|
||||
[model]
|
||||
);
|
||||
|
||||
const isItemLoaded = useCallback((index) => {
|
||||
if (!pages || !local.current.validPages) {
|
||||
return false;
|
||||
}
|
||||
local.current.checkIdx = index;
|
||||
const page = pages.filter((p) => p.qArea.qTop <= index && index < p.qArea.qTop + p.qArea.qHeight)[0];
|
||||
return page && page.qArea.qTop <= index && index < page.qArea.qTop + page.qArea.qHeight;
|
||||
}, [layout, pages]);
|
||||
const isItemLoaded = useCallback(
|
||||
index => {
|
||||
if (!pages || !local.current.validPages) {
|
||||
return false;
|
||||
}
|
||||
local.current.checkIdx = index;
|
||||
const page = pages.filter(p => p.qArea.qTop <= index && index < p.qArea.qTop + p.qArea.qHeight)[0];
|
||||
return page && page.qArea.qTop <= index && index < page.qArea.qTop + page.qArea.qHeight;
|
||||
},
|
||||
[layout, pages]
|
||||
);
|
||||
|
||||
const loadMoreItems = useCallback((startIndex, stopIndex) => {
|
||||
local.current.queue.push({
|
||||
start: startIndex,
|
||||
stop: stopIndex,
|
||||
});
|
||||
const loadMoreItems = useCallback(
|
||||
(startIndex, stopIndex) => {
|
||||
local.current.queue.push({
|
||||
start: startIndex,
|
||||
stop: stopIndex,
|
||||
});
|
||||
|
||||
const isScrolling = loaderRef.current ? loaderRef.current._listRef.state.isScrolling : false;
|
||||
const isScrolling = loaderRef.current ? loaderRef.current._listRef.state.isScrolling : false;
|
||||
|
||||
if (local.current.queue.length > 10) {
|
||||
local.current.queue.shift();
|
||||
}
|
||||
clearTimeout(local.current.timeout);
|
||||
return new Promise((resolve) => {
|
||||
local.current.timeout = setTimeout(() => {
|
||||
const sorted = local.current.queue.slice(-2).sort((a, b) => a.start - b.start);
|
||||
model.getListObjectData('/qListObjectDef', sorted.map((s) => ({
|
||||
qTop: s.start,
|
||||
qHeight: s.stop - s.start + 1,
|
||||
qLeft: 0,
|
||||
qWidth: 1,
|
||||
}))).then((p) => {
|
||||
local.current.validPages = true;
|
||||
listData.current.pages = p;
|
||||
setPages(p);
|
||||
resolve();
|
||||
});
|
||||
}, isScrolling ? 500 : 0);
|
||||
});
|
||||
}, [layout]);
|
||||
if (local.current.queue.length > 10) {
|
||||
local.current.queue.shift();
|
||||
}
|
||||
clearTimeout(local.current.timeout);
|
||||
return new Promise(resolve => {
|
||||
local.current.timeout = setTimeout(
|
||||
() => {
|
||||
const sorted = local.current.queue.slice(-2).sort((a, b) => a.start - b.start);
|
||||
model
|
||||
.getListObjectData(
|
||||
'/qListObjectDef',
|
||||
sorted.map(s => ({
|
||||
qTop: s.start,
|
||||
qHeight: s.stop - s.start + 1,
|
||||
qLeft: 0,
|
||||
qWidth: 1,
|
||||
}))
|
||||
)
|
||||
.then(p => {
|
||||
local.current.validPages = true;
|
||||
listData.current.pages = p;
|
||||
setPages(p);
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
isScrolling ? 500 : 0
|
||||
);
|
||||
});
|
||||
},
|
||||
[layout]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
local.current.queue = [];
|
||||
|
||||
@@ -1,55 +1,53 @@
|
||||
import React, {
|
||||
useCallback,
|
||||
} from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import Lock from '@nebula.js/ui/icons/Lock';
|
||||
import Unlock from '@nebula.js/ui/icons/Unlock';
|
||||
|
||||
import {
|
||||
IconButton,
|
||||
Popover,
|
||||
Grid,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { IconButton, Popover, Grid } from '@nebula.js/ui/components';
|
||||
|
||||
import useModel from '../../hooks/useModel';
|
||||
import useLayout from '../../hooks/useLayout';
|
||||
|
||||
import ListBox from './ListBox';
|
||||
|
||||
export default function ListBoxPopover({
|
||||
alignTo,
|
||||
show,
|
||||
close,
|
||||
app,
|
||||
selections,
|
||||
fieldName,
|
||||
stateName = '$',
|
||||
}) {
|
||||
const [model] = useModel({
|
||||
qInfo: {
|
||||
qType: 'dummy',
|
||||
},
|
||||
qListObjectDef: {
|
||||
qStateName: stateName,
|
||||
qShowAlternatives: true,
|
||||
qFrequencyMode: 'N',
|
||||
qReverseSort: false,
|
||||
qInitialDataFetch: [{
|
||||
qTop: 0, qLeft: 0, qHeight: 0, qWidth: 1,
|
||||
}],
|
||||
qDef: {
|
||||
qSortCriterias: [{
|
||||
qSortByExpression: 0,
|
||||
qSortByFrequency: 0,
|
||||
qSortByGreyness: 0,
|
||||
qSortByLoadOrder: 1,
|
||||
qSortByNumeric: 1,
|
||||
qSortByState: 1,
|
||||
}],
|
||||
qFieldDefs: [fieldName],
|
||||
export default function ListBoxPopover({ alignTo, show, close, app, selections, fieldName, stateName = '$' }) {
|
||||
const [model] = useModel(
|
||||
{
|
||||
qInfo: {
|
||||
qType: 'dummy',
|
||||
},
|
||||
qListObjectDef: {
|
||||
qStateName: stateName,
|
||||
qShowAlternatives: true,
|
||||
qFrequencyMode: 'N',
|
||||
qReverseSort: false,
|
||||
qInitialDataFetch: [
|
||||
{
|
||||
qTop: 0,
|
||||
qLeft: 0,
|
||||
qHeight: 0,
|
||||
qWidth: 1,
|
||||
},
|
||||
],
|
||||
qDef: {
|
||||
qSortCriterias: [
|
||||
{
|
||||
qSortByExpression: 0,
|
||||
qSortByFrequency: 0,
|
||||
qSortByGreyness: 0,
|
||||
qSortByLoadOrder: 1,
|
||||
qSortByNumeric: 1,
|
||||
qSortByState: 1,
|
||||
},
|
||||
],
|
||||
qFieldDefs: [fieldName],
|
||||
},
|
||||
},
|
||||
},
|
||||
}, app, fieldName, stateName);
|
||||
app,
|
||||
fieldName,
|
||||
stateName
|
||||
);
|
||||
|
||||
const lock = useCallback(() => {
|
||||
model.lock('/qListObjectDef');
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
Grid,
|
||||
Typography,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { Grid, Typography } from '@nebula.js/ui/components';
|
||||
|
||||
import { makeStyles } from '@nebula.js/ui/theme';
|
||||
|
||||
import Lock from '@nebula.js/ui/icons/Lock';
|
||||
import Tick from '@nebula.js/ui/icons/Tick';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
const useStyles = makeStyles(theme => ({
|
||||
row: {
|
||||
flexWrap: 'nowrap',
|
||||
borderBottom: `1px solid ${theme.palette.divider}`,
|
||||
@@ -39,11 +36,7 @@ const useStyles = makeStyles((theme) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
export default function Row({
|
||||
index,
|
||||
style,
|
||||
data,
|
||||
}) {
|
||||
export default function Row({ index, style, data }) {
|
||||
const classes = useStyles();
|
||||
const classArr = [classes.row];
|
||||
|
||||
@@ -51,10 +44,10 @@ export default function Row({
|
||||
const { onClick, pages } = data;
|
||||
let cell;
|
||||
if (pages) {
|
||||
const page = pages.filter((p) => p.qArea.qTop <= index && index < p.qArea.qTop + p.qArea.qHeight)[0];
|
||||
const page = pages.filter(p => p.qArea.qTop <= index && index < p.qArea.qTop + p.qArea.qHeight)[0];
|
||||
if (page) {
|
||||
const area = page.qArea;
|
||||
if (index >= area.qTop && (index < area.qTop + area.qHeight)) {
|
||||
if (index >= area.qTop && index < area.qTop + area.qHeight) {
|
||||
[cell] = page.qMatrix[index - area.qTop];
|
||||
}
|
||||
}
|
||||
@@ -86,12 +79,12 @@ export default function Row({
|
||||
>
|
||||
<Grid item style={{ minWidth: 0, flexGrow: 1 }}>
|
||||
<Typography className={classes.cell} noWrap>
|
||||
{cell ? `${label}` : '' }
|
||||
{cell ? `${label}` : ''}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item className={classes.icon}>
|
||||
{locked && (<Lock size="small" />)}
|
||||
{selected && (<Tick size="small" />)}
|
||||
{locked && <Lock size="small" />}
|
||||
{selected && <Tick size="small" />}
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import {
|
||||
Grid,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { Grid } from '@nebula.js/ui/components';
|
||||
|
||||
import {
|
||||
useTheme,
|
||||
} from '@nebula.js/ui/theme';
|
||||
import { useTheme } from '@nebula.js/ui/theme';
|
||||
|
||||
import SelectedFields from './SelectedFields';
|
||||
import Nav from './Nav';
|
||||
|
||||
export function AppSelections({
|
||||
api,
|
||||
}) {
|
||||
export function AppSelections({ api }) {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
@@ -42,14 +36,6 @@ export function AppSelections({
|
||||
);
|
||||
}
|
||||
|
||||
export default function mount({
|
||||
element,
|
||||
api,
|
||||
}) {
|
||||
return ReactDOM.createPortal(
|
||||
<AppSelections
|
||||
api={api}
|
||||
/>,
|
||||
element,
|
||||
);
|
||||
export default function mount({ element, api }) {
|
||||
return ReactDOM.createPortal(<AppSelections api={api} />, element);
|
||||
}
|
||||
|
||||
@@ -6,18 +6,13 @@ import {
|
||||
Typography,
|
||||
} from '@nebula.js/ui/components';
|
||||
|
||||
export default function MultiState({
|
||||
field,
|
||||
}) {
|
||||
export default function MultiState({ field }) {
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
spacing={0}
|
||||
alignItems="center"
|
||||
style={{ height: '100%', padding: '4px' }}
|
||||
>
|
||||
<Grid container spacing={0} alignItems="center" style={{ height: '100%', padding: '4px' }}>
|
||||
<Grid item style={{ minWidth: 0 }}>
|
||||
<Typography noWrap style={{ fontSize: '12px', lineHeight: '16px', fontWeight: 600 }}>{field.name}</Typography>
|
||||
<Typography noWrap style={{ fontSize: '12px', lineHeight: '16px', fontWeight: 600 }}>
|
||||
{field.name}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import React, {
|
||||
useEffect,
|
||||
useState,
|
||||
useContext,
|
||||
} from 'react';
|
||||
import React, { useEffect, useState, useContext } from 'react';
|
||||
|
||||
import {
|
||||
IconButton,
|
||||
Grid,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { IconButton, Grid } from '@nebula.js/ui/components';
|
||||
|
||||
import SelectionsBack from '@nebula.js/ui/icons/SelectionsBack';
|
||||
import SelectionsForward from '@nebula.js/ui/icons/SelectionsForward';
|
||||
@@ -15,9 +8,7 @@ import ClearSelections from '@nebula.js/ui/icons/ClearSelections';
|
||||
|
||||
import LocaleContext from '../../contexts/LocaleContext';
|
||||
|
||||
export default function Nav({
|
||||
api,
|
||||
}) {
|
||||
export default function Nav({ api }) {
|
||||
const translator = useContext(LocaleContext);
|
||||
|
||||
const [state, setState] = useState({
|
||||
@@ -30,11 +21,12 @@ export default function Nav({
|
||||
if (!api) {
|
||||
return undefined;
|
||||
}
|
||||
const onChange = () => setState({
|
||||
forward: api.canGoForward(),
|
||||
back: api.canGoBack(),
|
||||
clear: api.canClear(),
|
||||
});
|
||||
const onChange = () =>
|
||||
setState({
|
||||
forward: api.canGoForward(),
|
||||
back: api.canGoBack(),
|
||||
clear: api.canClear(),
|
||||
});
|
||||
api.on('changed', onChange);
|
||||
return () => {
|
||||
api.removeListener('changed', onChange);
|
||||
@@ -72,11 +64,7 @@ export default function Nav({
|
||||
</IconButton>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<IconButton
|
||||
disabled={!state.clear}
|
||||
title={translator.get('Selection.ClearAll')}
|
||||
onClick={() => api.clear()}
|
||||
>
|
||||
<IconButton disabled={!state.clear} title={translator.get('Selection.ClearAll')} onClick={() => api.clear()}>
|
||||
<ClearSelections />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
import React, {
|
||||
useRef,
|
||||
useState,
|
||||
useContext,
|
||||
} from 'react';
|
||||
import React, { useRef, useState, useContext } from 'react';
|
||||
|
||||
import Remove from '@nebula.js/ui/icons/Remove';
|
||||
import Lock from '@nebula.js/ui/icons/Lock';
|
||||
// import themes from '@nebula.js/ui/theme';
|
||||
|
||||
import {
|
||||
IconButton,
|
||||
Grid,
|
||||
Typography,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { IconButton, Grid, Typography } from '@nebula.js/ui/components';
|
||||
|
||||
import { makeStyles } from '@nebula.js/ui/theme';
|
||||
|
||||
@@ -20,7 +12,7 @@ import ListBoxPopover from '../listbox/ListBoxPopover';
|
||||
|
||||
import LocaleContext from '../../contexts/LocaleContext';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
const useStyles = makeStyles(theme => ({
|
||||
item: {
|
||||
cursor: 'pointer',
|
||||
padding: '4px',
|
||||
@@ -41,8 +33,9 @@ export default function OneField({
|
||||
|
||||
const classes = useStyles();
|
||||
|
||||
const toggleActive = (e) => {
|
||||
if (e.currentTarget.contains(e.target)) { // because click in popover will propagate to parent
|
||||
const toggleActive = e => {
|
||||
if (e.currentTarget.contains(e.target)) {
|
||||
// because click in popover will propagate to parent
|
||||
setIsActive(!isActive);
|
||||
}
|
||||
};
|
||||
@@ -60,7 +53,7 @@ export default function OneField({
|
||||
} else if (numSelected > 1 && selection.qTotal) {
|
||||
label = translator.get('CurrentSelections.Of', [numSelected, selection.qTotal]);
|
||||
} else {
|
||||
label = selection.qSelectedFieldSelectionInfo.map((v) => v.qName).join(', ');
|
||||
label = selection.qSelectedFieldSelectionInfo.map(v => v.qName).join(', ');
|
||||
}
|
||||
if (field.states[0] !== '$') {
|
||||
label = `${field.states[0]}: ${label}`;
|
||||
@@ -76,26 +69,29 @@ export default function OneField({
|
||||
});
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
spacing={0}
|
||||
ref={alignTo}
|
||||
className={classes.item}
|
||||
onClick={toggleActive}
|
||||
>
|
||||
<Grid
|
||||
item
|
||||
xs
|
||||
style={{ minWidth: 0, flexGrow: 1, opacity: selection.qLocked ? '0.3' : '' }}
|
||||
>
|
||||
<Typography noWrap style={{ fontSize: '12px', lineHeight: '16px', fontWeight: 600 }}>{selection.qField}</Typography>
|
||||
<Typography noWrap style={{ fontSize: '12px', opacity: 0.55, lineHeight: '16px' }}>{label}</Typography>
|
||||
<Grid container spacing={0} ref={alignTo} className={classes.item} onClick={toggleActive}>
|
||||
<Grid item xs style={{ minWidth: 0, flexGrow: 1, opacity: selection.qLocked ? '0.3' : '' }}>
|
||||
<Typography noWrap style={{ fontSize: '12px', lineHeight: '16px', fontWeight: 600 }}>
|
||||
{selection.qField}
|
||||
</Typography>
|
||||
<Typography noWrap style={{ fontSize: '12px', opacity: 0.55, lineHeight: '16px' }}>
|
||||
{label}
|
||||
</Typography>
|
||||
</Grid>
|
||||
{selection.qLocked ? (<Grid item><IconButton><Lock /></IconButton></Grid>) : (
|
||||
{selection.qLocked ? (
|
||||
<Grid item>
|
||||
<IconButton>
|
||||
<Lock />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
) : (
|
||||
<Grid item>
|
||||
<IconButton
|
||||
title={translator.get('Selection.Clear')}
|
||||
onClick={(e) => { e.stopPropagation(); api.clearField(selection.qField, field.states[0]); }}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
api.clearField(selection.qField, field.states[0]);
|
||||
}}
|
||||
style={{ zIndex: 1 }}
|
||||
>
|
||||
<Remove />
|
||||
@@ -111,7 +107,7 @@ export default function OneField({
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
{segments.map((s) => (
|
||||
{segments.map(s => (
|
||||
<div
|
||||
key={s.color}
|
||||
style={{
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import React, {
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import {
|
||||
Grid,
|
||||
} from '@nebula.js/ui/components';
|
||||
import { Grid } from '@nebula.js/ui/components';
|
||||
|
||||
import { useTheme } from '@nebula.js/ui/theme';
|
||||
|
||||
@@ -13,7 +8,7 @@ import OneField from './OneField';
|
||||
import MultiState from './MultiState';
|
||||
|
||||
function collect(qSelectionObject, fields, state = '$') {
|
||||
qSelectionObject.qSelections.forEach((selection) => {
|
||||
qSelectionObject.qSelections.forEach(selection => {
|
||||
const name = selection.qField;
|
||||
const field = fields[name] = fields[name] || { name, states: [], selections: [] }; // eslint-disable-line
|
||||
if (field.states.indexOf(state) === -1) {
|
||||
@@ -32,14 +27,12 @@ function getItems(layout) {
|
||||
collect(layout.qSelectionObject, fields);
|
||||
}
|
||||
if (layout.alternateStates) {
|
||||
layout.alternateStates.forEach((s) => collect(s.qSelectionObject, fields, s.stateName));
|
||||
layout.alternateStates.forEach(s => collect(s.qSelectionObject, fields, s.stateName));
|
||||
}
|
||||
return Object.keys(fields).map((key) => fields[key]);
|
||||
return Object.keys(fields).map(key => fields[key]);
|
||||
}
|
||||
|
||||
export default function SelectedFields({
|
||||
api,
|
||||
}) {
|
||||
export default function SelectedFields({ api }) {
|
||||
const [state, setState] = useState({
|
||||
items: getItems(api.layout()),
|
||||
});
|
||||
@@ -50,9 +43,10 @@ export default function SelectedFields({
|
||||
if (!api) {
|
||||
return undefined;
|
||||
}
|
||||
const onChange = () => setState({
|
||||
items: getItems(api.layout()),
|
||||
});
|
||||
const onChange = () =>
|
||||
setState({
|
||||
items: getItems(api.layout()),
|
||||
});
|
||||
api.on('changed', onChange);
|
||||
return () => {
|
||||
api.removeListener('changed', onChange);
|
||||
@@ -61,7 +55,7 @@ export default function SelectedFields({
|
||||
|
||||
return (
|
||||
<Grid container spacing={0} wrap="nowrap">
|
||||
{state.items.map((s) => (
|
||||
{state.items.map(s => (
|
||||
<Grid
|
||||
item
|
||||
key={`${s.states.join('::')}::${s.name}`}
|
||||
@@ -73,7 +67,7 @@ export default function SelectedFields({
|
||||
borderRight: `1px solid ${theme.palette.divider}`,
|
||||
}}
|
||||
>
|
||||
{(s.states.length > 1 ? <MultiState field={s} /> : <OneField field={s} api={api} />)}
|
||||
{s.states.length > 1 ? <MultiState field={s} /> : <OneField field={s} api={api} />}
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
|
||||
@@ -14,12 +14,16 @@ const mock = ({
|
||||
},
|
||||
SelectedFields = () => <sf />,
|
||||
Nav = () => <nav />,
|
||||
} = {}) => aw.mock([
|
||||
['**/ui/components/index.js', () => components],
|
||||
['**/ui/theme/index.js', () => theme],
|
||||
['**/SelectedFields.jsx', () => SelectedFields],
|
||||
['**/Nav.jsx', () => Nav],
|
||||
], ['../AppSelections']);
|
||||
} = {}) =>
|
||||
aw.mock(
|
||||
[
|
||||
['**/ui/components/index.js', () => components],
|
||||
['**/ui/theme/index.js', () => theme],
|
||||
['**/SelectedFields.jsx', () => SelectedFields],
|
||||
['**/Nav.jsx', () => Nav],
|
||||
],
|
||||
['../AppSelections']
|
||||
);
|
||||
|
||||
describe('<AppSelections />', () => {
|
||||
let api;
|
||||
@@ -28,7 +32,7 @@ describe('<AppSelections />', () => {
|
||||
canGoForward: () => 'canGoForward',
|
||||
canGoBack: () => 'canGoBack',
|
||||
canClear: () => 'canClear',
|
||||
layout: () => (null),
|
||||
layout: () => null,
|
||||
back: sinon.spy(),
|
||||
forward: sinon.spy(),
|
||||
clear: sinon.spy(),
|
||||
@@ -43,19 +47,44 @@ describe('<AppSelections />', () => {
|
||||
const r = renderer.create(<AS api={api} />);
|
||||
|
||||
expect(r.toJSON()).to.eql({
|
||||
type: 'sp', props: {}, children: [{
|
||||
type: 'tp', props: {}, children: [{
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 'nav', props: {}, children: null,
|
||||
}],
|
||||
}, {
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 'sf', props: {}, children: null,
|
||||
}],
|
||||
}],
|
||||
}],
|
||||
}],
|
||||
type: 'sp',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'tp',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'nav',
|
||||
props: {},
|
||||
children: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'g',
|
||||
props: {},
|
||||
children: [
|
||||
{
|
||||
type: 'sf',
|
||||
props: {},
|
||||
children: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import {
|
||||
useState,
|
||||
useEffect,
|
||||
} from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
import {
|
||||
observe,
|
||||
unObserve,
|
||||
} from '../object/observer';
|
||||
import { observe, unObserve } from '../object/observer';
|
||||
|
||||
export default function useLayout(model) {
|
||||
const [layout, setLayout] = useState(null);
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import {
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import modelCache, { key } from '../object/model-cache';
|
||||
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import {
|
||||
useState,
|
||||
useEffect,
|
||||
} from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
import {
|
||||
observe,
|
||||
unObserve,
|
||||
} from '../object/observer';
|
||||
import { observe, unObserve } from '../object/observer';
|
||||
|
||||
export default function useProperties(model) {
|
||||
const [properties, setProperties] = useState(null);
|
||||
|
||||
@@ -30,7 +30,8 @@ const mergeConfigs = (base, c) => ({
|
||||
locale: {
|
||||
language: (c.locale ? c.locale.language : '') || base.locale.language,
|
||||
},
|
||||
types: [ // TODO - filter to avoid duplicates
|
||||
types: [
|
||||
// TODO - filter to avoid duplicates
|
||||
...(base.types || []),
|
||||
...(c.types || []),
|
||||
],
|
||||
@@ -71,13 +72,18 @@ function nuked(configuration = {}) {
|
||||
root,
|
||||
};
|
||||
|
||||
currentConfig.types.forEach((t) => context.types.register({
|
||||
name: t.name,
|
||||
version: t.version,
|
||||
}, {
|
||||
meta: t.meta,
|
||||
load: t.load,
|
||||
}));
|
||||
currentConfig.types.forEach(t =>
|
||||
context.types.register(
|
||||
{
|
||||
name: t.name,
|
||||
version: t.version,
|
||||
},
|
||||
{
|
||||
meta: t.meta,
|
||||
load: t.load,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
let selectionsApi = null;
|
||||
let selectionsComponentReference = null;
|
||||
@@ -122,7 +128,7 @@ function nuked(configuration = {}) {
|
||||
return api;
|
||||
}
|
||||
|
||||
nucleus.configured = (c) => nuked(mergeConfigs(configuration, c));
|
||||
nucleus.configured = c => nuked(mergeConfigs(configuration, c));
|
||||
|
||||
return nucleus;
|
||||
}
|
||||
|
||||
@@ -4,19 +4,19 @@ import enUs from './translations/en-US';
|
||||
|
||||
const DEFAULT_LOCALE = 'en-US';
|
||||
|
||||
const SUPPORTED_LANGUAGES = [{
|
||||
info: {
|
||||
short: 'en',
|
||||
long: 'en-US',
|
||||
label: 'English',
|
||||
translatedLabel: 'Common.English',
|
||||
const SUPPORTED_LANGUAGES = [
|
||||
{
|
||||
info: {
|
||||
short: 'en',
|
||||
long: 'en-US',
|
||||
label: 'English',
|
||||
translatedLabel: 'Common.English',
|
||||
},
|
||||
data: enUs,
|
||||
},
|
||||
data: enUs,
|
||||
}];
|
||||
];
|
||||
|
||||
export default function locale({
|
||||
language,
|
||||
} = {}) {
|
||||
export default function locale({ language } = {}) {
|
||||
const translator = translatorFn();
|
||||
|
||||
const api = {
|
||||
@@ -27,7 +27,7 @@ export default function locale({
|
||||
translator: () => translator.api,
|
||||
};
|
||||
|
||||
SUPPORTED_LANGUAGES.forEach((d) => translator.addLanguage(d.info, d.data));
|
||||
SUPPORTED_LANGUAGES.forEach(d => translator.addLanguage(d.info, d.data));
|
||||
|
||||
api.locale(language || DEFAULT_LOCALE);
|
||||
|
||||
|
||||
@@ -7,8 +7,9 @@ const format = (message = '', args = []) => {
|
||||
};
|
||||
|
||||
const getLongLanguageCode = (lang, list) => {
|
||||
const code = list.filter((item) => item.long.toLowerCase() === lang.toLowerCase())[0]
|
||||
|| list.filter((item) => item.short.toLowerCase() === lang.toLowerCase())[0];
|
||||
const code =
|
||||
list.filter(item => item.long.toLowerCase() === lang.toLowerCase())[0] ||
|
||||
list.filter(item => item.short.toLowerCase() === lang.toLowerCase())[0];
|
||||
|
||||
if (!code) {
|
||||
console.warn(`Language '${lang}' not supported, falling back to ${DEFAULT_LANGUAGE}`);
|
||||
@@ -40,7 +41,7 @@ export default function translator() {
|
||||
};
|
||||
|
||||
return {
|
||||
setLanguage: (code) => {
|
||||
setLanguage: code => {
|
||||
currentLocale = code;
|
||||
// TODO - emit change?
|
||||
},
|
||||
@@ -48,7 +49,7 @@ export default function translator() {
|
||||
languageList.push(descr);
|
||||
api.append(data, descr.long);
|
||||
},
|
||||
getLongCode: (lang) => getLongLanguageCode(lang, languageList),
|
||||
getLongCode: lang => getLongLanguageCode(lang, languageList),
|
||||
api,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import {
|
||||
observe,
|
||||
unObserve,
|
||||
cache,
|
||||
} from '../observer';
|
||||
import { observe, unObserve, cache } from '../observer';
|
||||
|
||||
describe('observer', () => {
|
||||
beforeEach(() => {
|
||||
Object.keys(cache).forEach((key) => delete cache[key]);
|
||||
Object.keys(cache).forEach(key => delete cache[key]);
|
||||
});
|
||||
|
||||
describe('observe', () => {
|
||||
@@ -60,16 +56,16 @@ describe('observer', () => {
|
||||
it('should not call callbacks if model state is CLOSED, CLOSING or CANCELLED', async () => {
|
||||
const cb = sinon.spy();
|
||||
let onChanged;
|
||||
const layoutPromise0 = new Promise((resolve) => {
|
||||
const layoutPromise0 = new Promise(resolve => {
|
||||
setTimeout(resolve, 10);
|
||||
});
|
||||
const layoutPromise1 = new Promise((resolve) => {
|
||||
const layoutPromise1 = new Promise(resolve => {
|
||||
setTimeout(resolve, 10);
|
||||
});
|
||||
const layoutPromise2 = new Promise((resolve) => {
|
||||
const layoutPromise2 = new Promise(resolve => {
|
||||
setTimeout(resolve, 10);
|
||||
});
|
||||
const layoutPromise3 = new Promise((resolve) => {
|
||||
const layoutPromise3 = new Promise(resolve => {
|
||||
setTimeout(resolve, 10);
|
||||
});
|
||||
const model = {
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
import populateData from './populator';
|
||||
|
||||
export default function create({
|
||||
type,
|
||||
version,
|
||||
fields,
|
||||
}, optional, context) {
|
||||
export default function create({ type, version, fields }, optional, context) {
|
||||
const t = context.nebbie.types.get({ name: type, version });
|
||||
return t.initialProperties(optional.properties)
|
||||
.then((mergedProps) => t.supernova().then((sn) => {
|
||||
return t.initialProperties(optional.properties).then(mergedProps =>
|
||||
t.supernova().then(sn => {
|
||||
if (fields) {
|
||||
populateData({
|
||||
sn,
|
||||
properties: mergedProps,
|
||||
fields,
|
||||
}, context);
|
||||
populateData(
|
||||
{
|
||||
sn,
|
||||
properties: mergedProps,
|
||||
fields,
|
||||
},
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
return context.app.createSessionObject(mergedProps)
|
||||
.then((model) => context.nebbie.get({
|
||||
id: model.id,
|
||||
}, { ...optional, properties: {} }));
|
||||
}));
|
||||
return context.app.createSessionObject(mergedProps).then(model =>
|
||||
context.nebbie.get(
|
||||
{
|
||||
id: model.id,
|
||||
},
|
||||
{ ...optional, properties: {} }
|
||||
)
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
import vizualizationAPI from '../viz';
|
||||
import ObjectAPI from './object-api';
|
||||
|
||||
export function observe(model, objectAPI) {
|
||||
const onChanged = () => model.getLayout().then((layout) => {
|
||||
objectAPI.setLayout(layout);
|
||||
});
|
||||
const onChanged = () =>
|
||||
model.getLayout().then(layout => {
|
||||
objectAPI.setLayout(layout);
|
||||
});
|
||||
model.on('changed', onChanged);
|
||||
model.once('closed', () => {
|
||||
model.removeListener('changed', onChanged);
|
||||
@@ -16,7 +16,7 @@ export function observe(model, objectAPI) {
|
||||
}
|
||||
|
||||
export default function initiate(getCfg, optional, context) {
|
||||
return context.app.getObject(getCfg.id).then((model) => {
|
||||
return context.app.getObject(getCfg.id).then(model => {
|
||||
const viz = vizualizationAPI({
|
||||
model,
|
||||
context,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const idGen = [[10, 31], [0, 31], [0, 31], [0, 31], [0, 31], [0, 31]];
|
||||
function toChar([min, max]) {
|
||||
return (min + (Math.random() * (max - min) | 0)).toString(32);
|
||||
return (min + ((Math.random() * (max - min)) | 0)).toString(32);
|
||||
}
|
||||
|
||||
function uid() {
|
||||
@@ -30,19 +30,21 @@ function removeIndex(array, index) {
|
||||
return removeIdx;
|
||||
}
|
||||
|
||||
const nxDimension = (f) => ({
|
||||
const nxDimension = f => ({
|
||||
qDef: {
|
||||
qFieldDefs: [f],
|
||||
qSortCriterias: [{
|
||||
qSortByLoadOrder: 1,
|
||||
qSortByNumeric: 1,
|
||||
qSortByAscii: 1,
|
||||
}],
|
||||
qSortCriterias: [
|
||||
{
|
||||
qSortByLoadOrder: 1,
|
||||
qSortByNumeric: 1,
|
||||
qSortByAscii: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
qOtherTotalSpec: {},
|
||||
});
|
||||
|
||||
const nxMeasure = (f) => ({
|
||||
const nxMeasure = f => ({
|
||||
qDef: {
|
||||
qDef: f,
|
||||
},
|
||||
@@ -52,10 +54,7 @@ const nxMeasure = (f) => ({
|
||||
},
|
||||
});
|
||||
|
||||
export default function hcHandler({
|
||||
hc,
|
||||
def,
|
||||
}) {
|
||||
export default function hcHandler({ hc, def }) {
|
||||
hc.qDimensions = hc.qDimensions || [];
|
||||
hc.qMeasures = hc.qMeasures || [];
|
||||
hc.qInterColumnSortOrder = hc.qInterColumnSortOrder || [];
|
||||
@@ -70,10 +69,13 @@ export default function hcHandler({
|
||||
return hc.qMeasures;
|
||||
},
|
||||
addDimension(d) {
|
||||
const dimension = typeof d === 'string' ? nxDimension(d) : {
|
||||
...d,
|
||||
qDef: d.qDef || {},
|
||||
};
|
||||
const dimension =
|
||||
typeof d === 'string'
|
||||
? nxDimension(d)
|
||||
: {
|
||||
...d,
|
||||
qDef: d.qDef || {},
|
||||
};
|
||||
dimension.qDef.cId = dimension.qDef.cId || uid();
|
||||
dimension.qOtherTotalSpec = dimension.qOtherTotalSpec || {};
|
||||
if (!dimension.qDef.cId) {
|
||||
@@ -97,10 +99,13 @@ export default function hcHandler({
|
||||
def.dimensions.remove(dimension, objectProperties, idx);
|
||||
},
|
||||
addMeasure(m) {
|
||||
const measure = typeof m === 'string' ? nxMeasure(m) : {
|
||||
...m,
|
||||
qDef: m.qDef || {},
|
||||
};
|
||||
const measure =
|
||||
typeof m === 'string'
|
||||
? nxMeasure(m)
|
||||
: {
|
||||
...m,
|
||||
qDef: m.qDef || {},
|
||||
};
|
||||
measure.qDef.cId = measure.qDef.cId || uid();
|
||||
if (!measure.qDef.cId) {
|
||||
measure.qDef.cId = uid();
|
||||
|
||||
@@ -37,8 +37,7 @@ export default class ObjectAPI {
|
||||
const selections = this.state.sn ? this.state.sn.component.selections : null;
|
||||
if (selections && selections.id === this.model.id) {
|
||||
selections.setLayout(layout);
|
||||
if (layout.qSelectionInfo && layout.qSelectionInfo.qInSelections
|
||||
&& !selections.isModal()) {
|
||||
if (layout.qSelectionInfo && layout.qSelectionInfo.qInSelections && !selections.isModal()) {
|
||||
selections.goModal('/qHyperCubeDef'); // TODO - use path from data targets
|
||||
}
|
||||
if (!layout.qSelectionInfo || !layout.qSelectionInfo.qInSelections) {
|
||||
@@ -68,23 +67,27 @@ export default class ObjectAPI {
|
||||
if (!this.currentObjectType) {
|
||||
return this.context.config.env.Promise.resolve();
|
||||
}
|
||||
return this.context.nebbie.types.get({
|
||||
name: this.currentObjectType,
|
||||
version: this.currentSupernovaVersion,
|
||||
}).supernova().then((SN) => {
|
||||
// layout might have changed since we requested the new type,
|
||||
// make sure type in layout matches the requested one
|
||||
if (!this.state.layout || this.state.layout.visualization !== this.currentObjectType) {
|
||||
return this.context.config.env.Promise.resolve();
|
||||
}
|
||||
return this.setSupernova(SN);
|
||||
}).catch((e) => {
|
||||
this.setState({
|
||||
error: {
|
||||
message: `${e.message}`,
|
||||
},
|
||||
return this.context.nebbie.types
|
||||
.get({
|
||||
name: this.currentObjectType,
|
||||
version: this.currentSupernovaVersion,
|
||||
})
|
||||
.supernova()
|
||||
.then(SN => {
|
||||
// layout might have changed since we requested the new type,
|
||||
// make sure type in layout matches the requested one
|
||||
if (!this.state.layout || this.state.layout.visualization !== this.currentObjectType) {
|
||||
return this.context.config.env.Promise.resolve();
|
||||
}
|
||||
return this.setSupernova(SN);
|
||||
})
|
||||
.catch(e => {
|
||||
this.setState({
|
||||
error: {
|
||||
message: `${e.message}`,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setLayout(layout) {
|
||||
|
||||
@@ -31,25 +31,27 @@ export function observe(model, callback, property = 'layout') {
|
||||
throw new Error(`'${property}' is not observable!`);
|
||||
}
|
||||
if (!cache[model.id]) {
|
||||
const onChanged = (filtered) => {
|
||||
const onChanged = filtered => {
|
||||
const c = cache[model.id];
|
||||
const affected = [];
|
||||
Object.keys(c.props).filter((key) => (filtered ? key === filtered : true)).forEach((key) => {
|
||||
c.props[key].state = STATES.INVALID;
|
||||
if (c.props[key].callbacks.length) {
|
||||
affected.push(key);
|
||||
}
|
||||
});
|
||||
Object.keys(c.props)
|
||||
.filter(key => (filtered ? key === filtered : true))
|
||||
.forEach(key => {
|
||||
c.props[key].state = STATES.INVALID;
|
||||
if (c.props[key].callbacks.length) {
|
||||
affected.push(key);
|
||||
}
|
||||
});
|
||||
|
||||
affected.forEach((key) => {
|
||||
affected.forEach(key => {
|
||||
c.props[key].state = STATES.VALIDATING;
|
||||
const method = OBSERVABLE[key].filter((m) => model[m])[0];
|
||||
model[method]().then((value) => {
|
||||
const method = OBSERVABLE[key].filter(m => model[m])[0];
|
||||
model[method]().then(value => {
|
||||
if (cache[model.id] && cache[model.id].props[key]) {
|
||||
if (cache[model.id].props[key].state < STATES.CLOSED && cache[model.id].props[key].state !== STATES.VALID) {
|
||||
cache[model.id].props[key].state = STATES.VALID;
|
||||
cache[model.id].props[key].value = value;
|
||||
cache[model.id].props[key].callbacks.forEach((cb) => cb(value));
|
||||
cache[model.id].props[key].callbacks.forEach(cb => cb(value));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -61,7 +63,7 @@ export function observe(model, callback, property = 'layout') {
|
||||
props: {},
|
||||
};
|
||||
|
||||
OBSERVABLE_KEYS.forEach((key) => {
|
||||
OBSERVABLE_KEYS.forEach(key => {
|
||||
cache[model.id].props[key] = {
|
||||
state: STATES.INVALID,
|
||||
callbacks: [],
|
||||
@@ -88,8 +90,8 @@ export function observe(model, callback, property = 'layout') {
|
||||
}
|
||||
|
||||
export function get(model, property) {
|
||||
return new Promise((resolve) => {
|
||||
const cb = (value) => {
|
||||
return new Promise(resolve => {
|
||||
const cb = value => {
|
||||
unObserve(model, cb, property);
|
||||
resolve(value);
|
||||
};
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import hcHandler from './hc-handler';
|
||||
|
||||
export default function populateData({
|
||||
sn,
|
||||
properties,
|
||||
fields,
|
||||
}, context) {
|
||||
export default function populateData({ sn, properties, fields }, context) {
|
||||
const target = sn.qae.data.targets[0];
|
||||
if (!target) {
|
||||
context.logger.warn('Attempting to add fields to an object without a specified data target');
|
||||
@@ -24,11 +20,13 @@ export default function populateData({
|
||||
def: target,
|
||||
});
|
||||
|
||||
fields.forEach((f) => {
|
||||
fields.forEach(f => {
|
||||
let type = 'dimension';
|
||||
if ((typeof f === 'string' && f[0] === '=')
|
||||
|| (typeof f === 'object' && f.qDef.qDef)
|
||||
|| (typeof f === 'object' && f.qLibraryId && f.qType === 'measure')) {
|
||||
if (
|
||||
(typeof f === 'string' && f[0] === '=') ||
|
||||
(typeof f === 'object' && f.qDef.qDef) ||
|
||||
(typeof f === 'object' && f.qLibraryId && f.qType === 'measure')
|
||||
) {
|
||||
type = 'measure';
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { observe } from '../object/observer';
|
||||
|
||||
const cache = {};
|
||||
|
||||
const create = (app) => {
|
||||
const create = app => {
|
||||
let canGoForward = false;
|
||||
let canGoBack = false;
|
||||
let canClear = false;
|
||||
@@ -26,7 +26,8 @@ const create = (app) => {
|
||||
api.emit('modal-unset');
|
||||
modalObject._selections.emit('deactivated');
|
||||
}
|
||||
if (object && object !== null) { // TODO check model state
|
||||
if (object && object !== null) {
|
||||
// TODO check model state
|
||||
modalObject = object;
|
||||
api.emit('modal', modalObject._selections);
|
||||
return modalObject.beginSelections(Array.isArray(path) ? path : [path]);
|
||||
@@ -70,47 +71,55 @@ const create = (app) => {
|
||||
return this.switchModal().then(() => app.clearAll());
|
||||
},
|
||||
clearField(field, state = '$') {
|
||||
return this.switchModal().then(() => app.getField(field, state).then((f) => f.clear()));
|
||||
return this.switchModal().then(() => app.getField(field, state).then(f => f.clear()));
|
||||
},
|
||||
};
|
||||
|
||||
eventmixin(api);
|
||||
|
||||
modelCache({
|
||||
qInfo: {
|
||||
qType: 'current-selections',
|
||||
modelCache(
|
||||
{
|
||||
qInfo: {
|
||||
qType: 'current-selections',
|
||||
},
|
||||
qSelectionObjectDef: {
|
||||
qStateName: '$',
|
||||
},
|
||||
alternateStates: [],
|
||||
},
|
||||
qSelectionObjectDef: {
|
||||
qStateName: '$',
|
||||
},
|
||||
alternateStates: [],
|
||||
}, app).then((model) => {
|
||||
observe(app, (appLayout) => {
|
||||
const states = [...appLayout.qStateNames].map((s) => ({
|
||||
app
|
||||
).then(model => {
|
||||
observe(app, appLayout => {
|
||||
const states = [...appLayout.qStateNames].map(s => ({
|
||||
stateName: s, // need this as reference in selection toolbar since qSelectionObject.qStateName is not in the layout
|
||||
qSelectionObjectDef: {
|
||||
qStateName: s,
|
||||
},
|
||||
}));
|
||||
const existingStates = (lyt ? lyt.alternateStates.map((s) => s.stateName) : []).join('::');
|
||||
const newStates = appLayout.qStateNames.map((s) => s).join('::');
|
||||
const existingStates = (lyt ? lyt.alternateStates.map(s => s.stateName) : []).join('::');
|
||||
const newStates = appLayout.qStateNames.map(s => s).join('::');
|
||||
if (existingStates !== newStates) {
|
||||
model.applyPatches([{
|
||||
qOp: 'replace',
|
||||
qPath: '/alternateStates',
|
||||
qValue: JSON.stringify(states),
|
||||
}], true);
|
||||
model.applyPatches(
|
||||
[
|
||||
{
|
||||
qOp: 'replace',
|
||||
qPath: '/alternateStates',
|
||||
qValue: JSON.stringify(states),
|
||||
},
|
||||
],
|
||||
true
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
observe(model, (layout) => {
|
||||
observe(model, layout => {
|
||||
canGoBack = false;
|
||||
canGoForward = false;
|
||||
canClear = false;
|
||||
[layout, ...layout.alternateStates].forEach((state) => {
|
||||
[layout, ...layout.alternateStates].forEach(state => {
|
||||
canGoBack = canGoBack || state.qSelectionObject.qBackCount > 0;
|
||||
canGoForward = canGoForward || state.qSelectionObject.qForwardCount > 0;
|
||||
canClear = canClear || state.qSelectionObject.qSelections.filter((s) => s.qLocked !== true).length > 0;
|
||||
canClear = canClear || state.qSelectionObject.qSelections.filter(s => s.qLocked !== true).length > 0;
|
||||
});
|
||||
lyt = layout;
|
||||
api.emit('changed');
|
||||
@@ -124,7 +133,7 @@ const create = (app) => {
|
||||
return api;
|
||||
};
|
||||
|
||||
export default function (app) {
|
||||
export default function(app) {
|
||||
if (!cache[app.id]) {
|
||||
cache[app.id] = {
|
||||
selections: null,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import EventEmitter from 'node-event-emitter';
|
||||
|
||||
export default function (obj) {
|
||||
export default function(obj) {
|
||||
/* eslint no-param-reassign: 0 */
|
||||
Object.keys(EventEmitter.prototype).forEach((key) => {
|
||||
Object.keys(EventEmitter.prototype).forEach(key => {
|
||||
obj[key] = EventEmitter.prototype[key];
|
||||
});
|
||||
EventEmitter.init(obj);
|
||||
|
||||
@@ -11,7 +11,7 @@ const event = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export default function (model, app) {
|
||||
export default function(model, app) {
|
||||
if (model._selections) {
|
||||
return model._selections;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ export default function (model, app) {
|
||||
return;
|
||||
}
|
||||
hasSelected = true;
|
||||
model[s.method](...s.params).then((qSuccess) => {
|
||||
model[s.method](...s.params).then(qSuccess => {
|
||||
if (!qSuccess) {
|
||||
this.clear();
|
||||
}
|
||||
@@ -77,7 +77,7 @@ export default function (model, app) {
|
||||
},
|
||||
isActive: () => isActive,
|
||||
isModal: () => appAPI().isModal(model),
|
||||
goModal: (paths) => appAPI().switchModal(model, paths, false),
|
||||
goModal: paths => appAPI().switchModal(model, paths, false),
|
||||
noModal: () => appAPI().switchModal(null, null, false),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
const mock = ({
|
||||
SNFactory = () => ({}),
|
||||
satisfies = () => false,
|
||||
load = () => null,
|
||||
} = {}) => aw.mock([
|
||||
['**/dist/supernova.js', () => SNFactory],
|
||||
['**/semver.js', () => ({ satisfies })],
|
||||
['**/load.js', () => ({ load })],
|
||||
], ['../type']);
|
||||
const mock = ({ SNFactory = () => ({}), satisfies = () => false, load = () => null } = {}) =>
|
||||
aw.mock(
|
||||
[
|
||||
['**/dist/supernova.js', () => SNFactory],
|
||||
['**/semver.js', () => ({ satisfies })],
|
||||
['**/load.js', () => ({ load })],
|
||||
],
|
||||
['../type']
|
||||
);
|
||||
|
||||
describe('type', () => {
|
||||
let c;
|
||||
|
||||
@@ -9,15 +9,19 @@ describe('types', () => {
|
||||
});
|
||||
|
||||
describe('factory', () => {
|
||||
const mock = ({
|
||||
createType = () => ({}),
|
||||
clearFromCache = () => {},
|
||||
} = {}) => aw.mock([
|
||||
['**/sn/type.js', () => createType],
|
||||
['**/sn/load.js', () => ({
|
||||
clearFromCache,
|
||||
})],
|
||||
], ['../types']);
|
||||
const mock = ({ createType = () => ({}), clearFromCache = () => {} } = {}) =>
|
||||
aw.mock(
|
||||
[
|
||||
['**/sn/type.js', () => createType],
|
||||
[
|
||||
'**/sn/load.js',
|
||||
() => ({
|
||||
clearFromCache,
|
||||
}),
|
||||
],
|
||||
],
|
||||
['../types']
|
||||
);
|
||||
|
||||
let c;
|
||||
let type;
|
||||
@@ -33,17 +37,21 @@ describe('types', () => {
|
||||
|
||||
it('should instantiate a type when registering', () => {
|
||||
c.register({ name: 'pie', version: '1.0.3' }, 'opts');
|
||||
expect(type).to.have.been.calledWithExactly({
|
||||
name: 'pie',
|
||||
version: '1.0.3',
|
||||
}, 'config', 'opts');
|
||||
expect(type).to.have.been.calledWithExactly(
|
||||
{
|
||||
name: 'pie',
|
||||
version: '1.0.3',
|
||||
},
|
||||
'config',
|
||||
'opts'
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw when registering an already registered version', () => {
|
||||
c.register({ name: 'pie', version: '1.0.3' }, 'opts');
|
||||
const fn = () => c.register({ name: 'pie', version: '1.0.3' }, 'opts');
|
||||
|
||||
expect(fn).to.throw('Supernova \'pie@1.0.3\' already registered.');
|
||||
expect(fn).to.throw("Supernova 'pie@1.0.3' already registered.");
|
||||
});
|
||||
|
||||
it('should find 1.5.1 as matching version from properties', () => {
|
||||
|
||||
@@ -3,32 +3,37 @@ const LOADED = {};
|
||||
export function load(name, version, config, loader) {
|
||||
const key = `${name}__${version}`;
|
||||
if (!LOADED[key]) {
|
||||
const p = (loader || config.load)({
|
||||
name,
|
||||
version,
|
||||
}, config.env);
|
||||
const p = (loader || config.load)(
|
||||
{
|
||||
name,
|
||||
version,
|
||||
},
|
||||
config.env
|
||||
);
|
||||
if (typeof p === 'undefined') {
|
||||
throw new Error(`Failed to load supernova: ${name}`);
|
||||
}
|
||||
if (typeof p === 'string') {
|
||||
throw new Error('Return value must be a Promise');
|
||||
}
|
||||
LOADED[key] = p.then((sn) => {
|
||||
if (!sn) {
|
||||
throw new Error('undefined supernova');
|
||||
}
|
||||
return sn;
|
||||
}).catch((e) => {
|
||||
console.error(e);
|
||||
throw new Error(`Failed to load supernova: ${name}`);
|
||||
});
|
||||
LOADED[key] = p
|
||||
.then(sn => {
|
||||
if (!sn) {
|
||||
throw new Error('undefined supernova');
|
||||
}
|
||||
return sn;
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e);
|
||||
throw new Error(`Failed to load supernova: ${name}`);
|
||||
});
|
||||
}
|
||||
|
||||
return LOADED[key];
|
||||
}
|
||||
|
||||
export function clearFromCache(name) {
|
||||
Object.keys(LOADED).forEach((key) => {
|
||||
Object.keys(LOADED).forEach(key => {
|
||||
if (key.split('__')[0] === name) {
|
||||
LOADED[key] = undefined;
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ export default function create(info, config, opts = {}) {
|
||||
const type = {
|
||||
name: info.name,
|
||||
version: info.version,
|
||||
supportsPropertiesVersion: (v) => {
|
||||
supportsPropertiesVersion: v => {
|
||||
if (v && meta && meta.deps && meta.deps.properties) {
|
||||
return satisfies(v, meta.deps.properties);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
supernova: () => load(type.name, type.version, config, opts.load)
|
||||
.then((SNDefinition) => {
|
||||
supernova: () =>
|
||||
load(type.name, type.version, config, opts.load).then(SNDefinition => {
|
||||
sn = sn || SNFactory(SNDefinition, config.env);
|
||||
stringified = JSON.stringify(sn.qae.properties);
|
||||
return sn;
|
||||
|
||||
@@ -2,10 +2,15 @@ import type from './type';
|
||||
import { clearFromCache } from './load';
|
||||
|
||||
export function semverSort(arr) {
|
||||
const unversioned = arr.filter((v) => v === 'undefined');
|
||||
return [...unversioned, ...arr.filter((v) => v !== 'undefined').map((v) => v.split('.').map((n) => parseInt(n, 10)))
|
||||
.sort((a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2])
|
||||
.map((n) => n.join('.'))];
|
||||
const unversioned = arr.filter(v => v === 'undefined');
|
||||
return [
|
||||
...unversioned,
|
||||
...arr
|
||||
.filter(v => v !== 'undefined')
|
||||
.map(v => v.split('.').map(n => parseInt(n, 10)))
|
||||
.sort((a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2])
|
||||
.map(n => n.join('.')),
|
||||
];
|
||||
}
|
||||
|
||||
export function typeCollection(name, config) {
|
||||
@@ -13,18 +18,22 @@ export function typeCollection(name, config) {
|
||||
let sortedVersions = null;
|
||||
|
||||
return {
|
||||
get: (version) => versions[version],
|
||||
get: version => versions[version],
|
||||
register: (version, opts) => {
|
||||
if (versions[version]) {
|
||||
throw new Error(`Supernova '${name}@${version}' already registered.`);
|
||||
}
|
||||
versions[version] = type({
|
||||
name,
|
||||
version,
|
||||
}, config, opts);
|
||||
versions[version] = type(
|
||||
{
|
||||
name,
|
||||
version,
|
||||
},
|
||||
config,
|
||||
opts
|
||||
);
|
||||
sortedVersions = null;
|
||||
},
|
||||
getMatchingVersionFromProperties: (propertyVersion) => {
|
||||
getMatchingVersionFromProperties: propertyVersion => {
|
||||
if (!sortedVersions) {
|
||||
sortedVersions = semverSort(Object.keys(versions));
|
||||
}
|
||||
@@ -40,9 +49,7 @@ export function typeCollection(name, config) {
|
||||
};
|
||||
}
|
||||
|
||||
export function create({
|
||||
config,
|
||||
}) {
|
||||
export function create({ config }) {
|
||||
const tc = {};
|
||||
|
||||
return {
|
||||
@@ -65,7 +72,7 @@ export function create({
|
||||
}
|
||||
return tc[name].get(version);
|
||||
},
|
||||
clearFromCache: (name) => {
|
||||
clearFromCache: name => {
|
||||
if (tc[name]) {
|
||||
tc[name] = undefined;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,7 @@ const LOG_LEVEL = {
|
||||
DEBUG: 4,
|
||||
};
|
||||
|
||||
const loggerFn = ({
|
||||
level = LOG_LEVEL.OFF,
|
||||
pipe = console,
|
||||
} = {}) => {
|
||||
const loggerFn = ({ level = LOG_LEVEL.OFF, pipe = console } = {}) => {
|
||||
let currentlevel = level;
|
||||
|
||||
const LOG_FN = {
|
||||
@@ -21,7 +18,9 @@ const loggerFn = ({
|
||||
};
|
||||
|
||||
const log = (lev, ...args) => {
|
||||
if (!lev || currentlevel < lev) { return; }
|
||||
if (!lev || currentlevel < lev) {
|
||||
return;
|
||||
}
|
||||
|
||||
(LOG_FN[lev] || LOG_FN[LOG_LEVEL.DEBUG])(...args);
|
||||
};
|
||||
@@ -68,7 +67,7 @@ const loggerFn = ({
|
||||
* Set the current log level
|
||||
* @param {number} lev - The log level
|
||||
*/
|
||||
level: (lev) => {
|
||||
level: lev => {
|
||||
if (typeof lev === 'number') {
|
||||
currentlevel = lev;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
function isObject(v) { return v != null && !Array.isArray(v) && typeof v === 'object'; }
|
||||
function isObject(v) {
|
||||
return v != null && !Array.isArray(v) && typeof v === 'object';
|
||||
}
|
||||
|
||||
function isEqual(a, b) {
|
||||
if (isObject(a) && isObject(b)) {
|
||||
@@ -12,7 +14,7 @@ function isEqual(a, b) {
|
||||
|
||||
export default function getPatches(path = '/', obj, old) {
|
||||
const patches = [];
|
||||
Object.keys(obj).forEach((prop) => {
|
||||
Object.keys(obj).forEach(prop => {
|
||||
const v = obj[prop];
|
||||
if (typeof old[prop] === 'object' && typeof v === 'object' && !Array.isArray(v)) {
|
||||
patches.push(...getPatches(`${path}${prop}/`, obj[prop], old[prop]));
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
/* eslint import/prefer-default-export: 0 */
|
||||
|
||||
export const prefixer = (list) => {
|
||||
export const prefixer = list => {
|
||||
const arr = Array.isArray(list) ? list : list.split(/\s+/);
|
||||
return arr.map((s) => {
|
||||
if (s[0] === '-' || s[0] === '_') {
|
||||
return `nucleus${s}`;
|
||||
}
|
||||
return `nucleus-${s}`;
|
||||
}).join(' ');
|
||||
return arr
|
||||
.map(s => {
|
||||
if (s[0] === '-' || s[0] === '_') {
|
||||
return `nucleus${s}`;
|
||||
}
|
||||
return `nucleus-${s}`;
|
||||
})
|
||||
.join(' ');
|
||||
};
|
||||
|
||||
@@ -7,11 +7,7 @@ import eventMixin from './selections/event-mixin';
|
||||
|
||||
const noopi = () => {};
|
||||
|
||||
export default function ({
|
||||
model,
|
||||
context,
|
||||
initialUserProps = {},
|
||||
} = {}) {
|
||||
export default function({ model, context, initialUserProps = {} } = {}) {
|
||||
let reference = noopi;
|
||||
let elementReference = null;
|
||||
|
||||
@@ -19,9 +15,15 @@ export default function ({
|
||||
let layoutReady;
|
||||
let mounted;
|
||||
|
||||
const whenLayoutReady = new Promise((resolve) => { layoutReady = resolve; });
|
||||
const whenSupernovaReady = new Promise((resolve) => { supernovaReady = resolve; });
|
||||
const whenMounted = new Promise((resolve) => { mounted = resolve; });
|
||||
const whenLayoutReady = new Promise(resolve => {
|
||||
layoutReady = resolve;
|
||||
});
|
||||
const whenSupernovaReady = new Promise(resolve => {
|
||||
supernovaReady = resolve;
|
||||
});
|
||||
const whenMounted = new Promise(resolve => {
|
||||
mounted = resolve;
|
||||
});
|
||||
|
||||
let userProps = {
|
||||
options: {},
|
||||
@@ -52,7 +54,7 @@ export default function ({
|
||||
cellApi.emit('changed');
|
||||
};
|
||||
|
||||
const setUserProps = (up) => {
|
||||
const setUserProps = up => {
|
||||
userProps = {
|
||||
...userProps,
|
||||
...up,
|
||||
@@ -60,7 +62,7 @@ export default function ({
|
||||
update();
|
||||
};
|
||||
|
||||
const setObjectProps = (p) => {
|
||||
const setObjectProps = p => {
|
||||
objectProps = {
|
||||
...objectProps,
|
||||
...p,
|
||||
@@ -82,10 +84,7 @@ export default function ({
|
||||
throw new Error('Already mounted');
|
||||
}
|
||||
elementReference = element;
|
||||
return Promise.all([
|
||||
whenLayoutReady,
|
||||
whenSupernovaReady,
|
||||
]).then(() => {
|
||||
return Promise.all([whenLayoutReady, whenSupernovaReady]).then(() => {
|
||||
reference = cell({
|
||||
element,
|
||||
model,
|
||||
@@ -103,7 +102,7 @@ export default function ({
|
||||
reference = noopi;
|
||||
},
|
||||
setTemporaryProperties(props) {
|
||||
return get(model, 'effectiveProperties').then((current) => {
|
||||
return get(model, 'effectiveProperties').then(current => {
|
||||
const patches = getPatches('/', props, current);
|
||||
if (patches.length) {
|
||||
return model.applyPatches(patches, true);
|
||||
|
||||
@@ -22,10 +22,7 @@ async function build(argv) {
|
||||
|
||||
const meta = argv.meta ? require(path.resolve(argv.meta)) : {}; // eslint-disable-line
|
||||
|
||||
const {
|
||||
module,
|
||||
main,
|
||||
} = supernovaPkg;
|
||||
const { module, main } = supernovaPkg;
|
||||
|
||||
const bundle = await rollup.rollup({
|
||||
input: {
|
||||
@@ -33,32 +30,31 @@ async function build(argv) {
|
||||
extDefinition,
|
||||
[extName]: path.resolve(__dirname, '../src/supernova-wrapper'),
|
||||
},
|
||||
external: [
|
||||
'snDefinition',
|
||||
'extDefinition',
|
||||
],
|
||||
external: ['snDefinition', 'extDefinition'],
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
common(),
|
||||
babel({
|
||||
babelrc: false,
|
||||
exclude: [
|
||||
/node_modules/,
|
||||
],
|
||||
exclude: [/node_modules/],
|
||||
presets: [
|
||||
['@babel/preset-env', {
|
||||
modules: false,
|
||||
targets: {
|
||||
browsers: ['ie 11', 'chrome 47'],
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
modules: false,
|
||||
targets: {
|
||||
browsers: ['ie 11', 'chrome 47'],
|
||||
},
|
||||
},
|
||||
}],
|
||||
],
|
||||
],
|
||||
}),
|
||||
(argv.minify && terser({
|
||||
output: {
|
||||
comments: /@license|@preserve|Copyright|license/,
|
||||
},
|
||||
})),
|
||||
argv.minify &&
|
||||
terser({
|
||||
output: {
|
||||
comments: /@license|@preserve|Copyright|license/,
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -77,7 +73,7 @@ async function build(argv) {
|
||||
// since that would cause requirejs in sense-client to interpret the request as text/html
|
||||
// so we trim off the file extension in the modules, but then attach it to the files
|
||||
const files = fs.readdirSync(targetDirectory);
|
||||
files.forEach((f) => {
|
||||
files.forEach(f => {
|
||||
if (/^chunk-/.test(f) && !/\.js$/.test(f)) {
|
||||
// attach file extension
|
||||
fs.renameSync(path.resolve(targetDirectory, f), path.resolve(targetDirectory, `${f}.js`));
|
||||
@@ -85,14 +81,21 @@ async function build(argv) {
|
||||
});
|
||||
|
||||
// write .qext for the extension
|
||||
fs.writeFileSync(path.resolve(targetDirectory, `${extName}.qext`), JSON.stringify({
|
||||
name: extName,
|
||||
description: supernovaPkg.description,
|
||||
author: supernovaPkg.author,
|
||||
version: supernovaPkg.version,
|
||||
...meta,
|
||||
type: 'visualization',
|
||||
}, null, 2));
|
||||
fs.writeFileSync(
|
||||
path.resolve(targetDirectory, `${extName}.qext`),
|
||||
JSON.stringify(
|
||||
{
|
||||
name: extName,
|
||||
description: supernovaPkg.description,
|
||||
author: supernovaPkg.author,
|
||||
version: supernovaPkg.version,
|
||||
...meta,
|
||||
type: 'visualization',
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = build;
|
||||
|
||||
@@ -29,38 +29,63 @@ const MODES = {
|
||||
describe('permissions', () => {
|
||||
describe('with live engine', () => {
|
||||
it('in STATIC mode should only allow model SELECT and FETCH', () => {
|
||||
expect(permissions({
|
||||
interactionState: 0,
|
||||
}, {})).to.eql(['select', 'fetch']);
|
||||
expect(
|
||||
permissions(
|
||||
{
|
||||
interactionState: 0,
|
||||
},
|
||||
{}
|
||||
)
|
||||
).to.eql(['select', 'fetch']);
|
||||
});
|
||||
|
||||
it('in ANALYSIS mode should allow everything', () => {
|
||||
expect(permissions({
|
||||
interactionState: 1,
|
||||
}, {})).to.eql(['passive', 'interact', 'select', 'fetch']);
|
||||
expect(
|
||||
permissions(
|
||||
{
|
||||
interactionState: 1,
|
||||
},
|
||||
{}
|
||||
)
|
||||
).to.eql(['passive', 'interact', 'select', 'fetch']);
|
||||
});
|
||||
|
||||
it('in EDIT mode should only allow model SELECT and FETCH', () => {
|
||||
expect(permissions({
|
||||
interactionState: 2,
|
||||
}, {})).to.eql(['select', 'fetch']);
|
||||
expect(
|
||||
permissions(
|
||||
{
|
||||
interactionState: 2,
|
||||
},
|
||||
{}
|
||||
)
|
||||
).to.eql(['select', 'fetch']);
|
||||
});
|
||||
|
||||
it('in ANALYSIS mode with tooltips and selections off, should only allow FETCH', () => {
|
||||
expect(permissions({
|
||||
interactionState: 1,
|
||||
tooltips: false,
|
||||
selections: false,
|
||||
}, {})).to.eql(['fetch']);
|
||||
expect(
|
||||
permissions(
|
||||
{
|
||||
interactionState: 1,
|
||||
tooltips: false,
|
||||
selections: false,
|
||||
},
|
||||
{}
|
||||
)
|
||||
).to.eql(['fetch']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for a snapshot', () => {
|
||||
// interactive chart snapshot (shared chart)
|
||||
it('in ANALYSIS mode should only allow PASSIVE and INTERACT', () => {
|
||||
expect(permissions({
|
||||
interactionState: 1,
|
||||
}, { isSnapshot: true })).to.eql(['passive', 'interact']);
|
||||
expect(
|
||||
permissions(
|
||||
{
|
||||
interactionState: 1,
|
||||
},
|
||||
{ isSnapshot: true }
|
||||
)
|
||||
).to.eql(['passive', 'interact']);
|
||||
});
|
||||
|
||||
// edit story
|
||||
|
||||
@@ -16,7 +16,11 @@ function permissions(options, backendApi) {
|
||||
if (showTooltip(options)) {
|
||||
p.push('passive');
|
||||
}
|
||||
if (options.interactionState === INTERACTION_STATES.ANALYSIS && options.tooltips !== false && options.limitedInteraction !== true) {
|
||||
if (
|
||||
options.interactionState === INTERACTION_STATES.ANALYSIS &&
|
||||
options.tooltips !== false &&
|
||||
options.limitedInteraction !== true
|
||||
) {
|
||||
p.push('interact');
|
||||
}
|
||||
if (!backendApi.isSnapshot) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import EventEmitter from 'node-event-emitter';
|
||||
|
||||
export default (scope) => {
|
||||
export default scope => {
|
||||
/* eslint no-param-reassign: 0 */
|
||||
const mixin = (obj) => {
|
||||
Object.keys(EventEmitter.prototype).forEach((key) => {
|
||||
const mixin = obj => {
|
||||
Object.keys(EventEmitter.prototype).forEach(key => {
|
||||
obj[key] = EventEmitter.prototype[key];
|
||||
});
|
||||
EventEmitter.init(obj);
|
||||
@@ -31,7 +31,7 @@ export default (scope) => {
|
||||
if (s.method !== 'resetMadeSelections' && !scope.selectionsApi.selectionsMade) {
|
||||
scope.backendApi.beginSelections();
|
||||
}
|
||||
scope.backendApi.model[s.method](...s.params).then((qSuccess) => {
|
||||
scope.backendApi.model[s.method](...s.params).then(qSuccess => {
|
||||
if (!qSuccess) {
|
||||
scope.selectionsApi.selectionsMade = false;
|
||||
this.clear();
|
||||
|
||||
@@ -33,7 +33,7 @@ const startEngine = () => {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
|
||||
c.on('exit', (code) => {
|
||||
c.on('exit', code => {
|
||||
if (code !== 0) {
|
||||
clear();
|
||||
reject();
|
||||
|
||||
@@ -6,16 +6,13 @@ const { watch } = require('@nebula.js/cli-build');
|
||||
|
||||
const webpackServe = require('./webpack.serve.js');
|
||||
|
||||
const {
|
||||
startEngine,
|
||||
stopEngine,
|
||||
} = require('./engine');
|
||||
const { startEngine, stopEngine } = require('./engine');
|
||||
|
||||
module.exports = async (argv) => {
|
||||
module.exports = async argv => {
|
||||
if (process.env.ACCEPT_EULA === 'yes') {
|
||||
await startEngine();
|
||||
}
|
||||
const port = argv.port || await portfinder.getPortPromise();
|
||||
const port = argv.port || (await portfinder.getPortPromise());
|
||||
const host = argv.host || 'localhost';
|
||||
const enigmaConfig = {
|
||||
port: 9076,
|
||||
@@ -70,7 +67,7 @@ module.exports = async (argv) => {
|
||||
server.close();
|
||||
};
|
||||
|
||||
['SIGINT', 'SIGTERM'].forEach((signal) => {
|
||||
['SIGINT', 'SIGTERM'].forEach(signal => {
|
||||
process.on(signal, close);
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import def from 'snDefinition'; // eslint-disable-line
|
||||
window.snDefinition = def;
|
||||
|
||||
let cb = () => {};
|
||||
window.hotReload = (fn) => {
|
||||
window.hotReload = fn => {
|
||||
cb = fn;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,24 +5,13 @@ const babelPath = require.resolve('babel-loader');
|
||||
const babelPresetEnvPath = require.resolve('@babel/preset-env');
|
||||
const babelPresetReactPath = require.resolve('@babel/preset-react');
|
||||
|
||||
const cfg = ({
|
||||
srcDir,
|
||||
distDir,
|
||||
snPath,
|
||||
dev = false,
|
||||
}) => {
|
||||
const cfg = ({ srcDir, distDir, snPath, dev = false }) => {
|
||||
const config = {
|
||||
mode: dev ? 'development' : 'production',
|
||||
entry: {
|
||||
eRender: [
|
||||
path.resolve(srcDir, 'eRender'),
|
||||
],
|
||||
eDev: [
|
||||
path.resolve(srcDir, 'eDev'),
|
||||
],
|
||||
eHub: [
|
||||
path.resolve(srcDir, 'eHub'),
|
||||
],
|
||||
eRender: [path.resolve(srcDir, 'eRender')],
|
||||
eDev: [path.resolve(srcDir, 'eDev')],
|
||||
eHub: [path.resolve(srcDir, 'eHub')],
|
||||
},
|
||||
devtool: 'source-map',
|
||||
output: {
|
||||
@@ -37,29 +26,30 @@ const cfg = ({
|
||||
},
|
||||
externals: dev ? {} : 'snDefinition',
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.jsx?$/,
|
||||
sideEffects: false,
|
||||
include: [
|
||||
srcDir,
|
||||
/nucleus/,
|
||||
/ui\/icons/,
|
||||
],
|
||||
use: {
|
||||
loader: babelPath,
|
||||
options: {
|
||||
presets: [
|
||||
[babelPresetEnvPath, {
|
||||
modules: false,
|
||||
targets: {
|
||||
browsers: ['last 2 chrome versions'],
|
||||
},
|
||||
}],
|
||||
babelPresetReactPath,
|
||||
],
|
||||
rules: [
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
sideEffects: false,
|
||||
include: [srcDir, /nucleus/, /ui\/icons/],
|
||||
use: {
|
||||
loader: babelPath,
|
||||
options: {
|
||||
presets: [
|
||||
[
|
||||
babelPresetEnvPath,
|
||||
{
|
||||
modules: false,
|
||||
targets: {
|
||||
browsers: ['last 2 chrome versions'],
|
||||
},
|
||||
},
|
||||
],
|
||||
babelPresetReactPath,
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}],
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
|
||||
@@ -4,10 +4,7 @@ const webpack = require('webpack');
|
||||
|
||||
const sourceMapLoaderPath = require.resolve('source-map-loader');
|
||||
|
||||
const cfg = ({
|
||||
srcDir = path.resolve(__dirname, '../dist'),
|
||||
snPath = path.resolve(__dirname, 'placeholder'),
|
||||
}) => {
|
||||
const cfg = ({ srcDir = path.resolve(__dirname, '../dist'), snPath = path.resolve(__dirname, 'placeholder') }) => {
|
||||
const config = {
|
||||
mode: 'development',
|
||||
entry: path.resolve(__dirname, './sn.js'),
|
||||
@@ -22,11 +19,13 @@ const cfg = ({
|
||||
},
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
enforce: 'pre',
|
||||
test: /\.js$/,
|
||||
loader: sourceMapLoaderPath,
|
||||
}],
|
||||
rules: [
|
||||
{
|
||||
enforce: 'pre',
|
||||
test: /\.js$/,
|
||||
loader: sourceMapLoaderPath,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
|
||||
@@ -5,16 +5,7 @@ const chalk = require('chalk');
|
||||
const webpack = require('webpack');
|
||||
const WebpackDevServer = require('webpack-dev-server');
|
||||
|
||||
module.exports = async ({
|
||||
host,
|
||||
port,
|
||||
enigmaConfig,
|
||||
snPath,
|
||||
snName,
|
||||
dev = false,
|
||||
open = true,
|
||||
watcher,
|
||||
}) => {
|
||||
module.exports = async ({ host, port, enigmaConfig, snPath, snName, dev = false, open = true, watcher }) => {
|
||||
let config;
|
||||
let contentBase;
|
||||
|
||||
@@ -50,9 +41,7 @@ module.exports = async ({
|
||||
},
|
||||
quiet: true,
|
||||
open,
|
||||
contentBase: [
|
||||
contentBase,
|
||||
],
|
||||
contentBase: [contentBase],
|
||||
historyApiFallback: {
|
||||
index: '/eHub.html',
|
||||
},
|
||||
@@ -66,15 +55,18 @@ module.exports = async ({
|
||||
});
|
||||
});
|
||||
},
|
||||
proxy: [{
|
||||
context: '/render',
|
||||
target: `http://${host}:${port}/eRender.html`,
|
||||
ignorePath: true,
|
||||
}, {
|
||||
context: '/dev',
|
||||
target: `http://${host}:${port}/eDev.html`,
|
||||
ignorePath: true,
|
||||
}],
|
||||
proxy: [
|
||||
{
|
||||
context: '/render',
|
||||
target: `http://${host}:${port}/eRender.html`,
|
||||
ignorePath: true,
|
||||
},
|
||||
{
|
||||
context: '/dev',
|
||||
target: `http://${host}:${port}/eDev.html`,
|
||||
ignorePath: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
console.log('Starting development server...');
|
||||
@@ -87,12 +79,12 @@ module.exports = async ({
|
||||
server.close();
|
||||
};
|
||||
|
||||
['SIGINT', 'SIGTERM'].forEach((signal) => {
|
||||
['SIGINT', 'SIGTERM'].forEach(signal => {
|
||||
process.on(signal, close);
|
||||
});
|
||||
|
||||
if (watcher) {
|
||||
watcher.on('event', (event) => {
|
||||
watcher.on('event', event => {
|
||||
if (event.code === 'ERROR') {
|
||||
server.sockWrite(server.sockets, 'errors', [event.error.stack]);
|
||||
}
|
||||
@@ -101,8 +93,9 @@ module.exports = async ({
|
||||
|
||||
let initiated = false;
|
||||
|
||||
return new Promise((resolve, reject) => { // eslint-disable-line consistent-return
|
||||
compiler.hooks.done.tap('nebula serve', (stats) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// eslint-disable-line consistent-return
|
||||
compiler.hooks.done.tap('nebula serve', stats => {
|
||||
if (!initiated) {
|
||||
initiated = true;
|
||||
const url = `http://${host}:${port}`;
|
||||
@@ -115,7 +108,7 @@ module.exports = async ({
|
||||
});
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
stats.compilation.errors.forEach((e) => {
|
||||
stats.compilation.errors.forEach(e => {
|
||||
console.log(chalk.red(e));
|
||||
});
|
||||
process.exit(1);
|
||||
@@ -123,7 +116,7 @@ module.exports = async ({
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(port, host, (err) => {
|
||||
server.listen(port, host, err => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
describe('creator', () => {
|
||||
const [{ default: create }] = aw.mock([
|
||||
['**/action-hero.js', () => () => ({})],
|
||||
], ['../../src/creator']);
|
||||
const [{ default: create }] = aw.mock([['**/action-hero.js', () => () => ({})]], ['../../src/creator']);
|
||||
|
||||
it('should return a default component api', () => {
|
||||
const generator = {
|
||||
@@ -16,14 +14,9 @@ describe('creator', () => {
|
||||
|
||||
const c = create(generator, params, env).component;
|
||||
|
||||
[
|
||||
'created',
|
||||
'mounted',
|
||||
'render',
|
||||
'resize',
|
||||
'willUnmount',
|
||||
'destroy',
|
||||
].forEach((key) => expect(c[key]).to.be.a('function'));
|
||||
['created', 'mounted', 'render', 'resize', 'willUnmount', 'destroy'].forEach(key =>
|
||||
expect(c[key]).to.be.a('function')
|
||||
);
|
||||
|
||||
expect(c.model).to.equal(params.model);
|
||||
expect(c.app).to.equal(params.app);
|
||||
@@ -50,14 +43,7 @@ describe('creator', () => {
|
||||
|
||||
const c = create(generator, params, env).component;
|
||||
|
||||
[
|
||||
'created',
|
||||
'mounted',
|
||||
'render',
|
||||
'resize',
|
||||
'willUnmount',
|
||||
'destroy',
|
||||
].forEach((key) => {
|
||||
['created', 'mounted', 'render', 'resize', 'willUnmount', 'destroy'].forEach(key => {
|
||||
c[key]('a');
|
||||
expect(generator.component[key]).to.have.been.calledWithExactly('a');
|
||||
});
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// import generator from '../../src/generator';
|
||||
|
||||
describe('generator', () => {
|
||||
const [{ default: generator }] = aw.mock([
|
||||
['**/creator.js', () => (...a) => [...a]],
|
||||
['**/qae.js', () => (qae) => qae || 'qae'],
|
||||
], ['../../src/generator']);
|
||||
const [{ default: generator }] = aw.mock(
|
||||
[['**/creator.js', () => (...a) => [...a]], ['**/qae.js', () => qae => qae || 'qae']],
|
||||
['../../src/generator']
|
||||
);
|
||||
|
||||
it('should have a default qae property', () => {
|
||||
expect(generator({}).qae).to.eql('qae');
|
||||
@@ -15,10 +15,12 @@ describe('generator', () => {
|
||||
});
|
||||
|
||||
it('should not override reserved properties', () => {
|
||||
expect(generator({
|
||||
foo: 'bar',
|
||||
component: 'c',
|
||||
}).definition).to.eql({
|
||||
expect(
|
||||
generator({
|
||||
foo: 'bar',
|
||||
component: 'c',
|
||||
}).definition
|
||||
).to.eql({
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
@@ -33,10 +35,13 @@ describe('generator', () => {
|
||||
});
|
||||
|
||||
it('should create an instance', () => {
|
||||
const g = generator({}, {
|
||||
translator: 't',
|
||||
Promise: 'P',
|
||||
});
|
||||
const g = generator(
|
||||
{},
|
||||
{
|
||||
translator: 't',
|
||||
Promise: 'P',
|
||||
}
|
||||
);
|
||||
const ret = g.create('a');
|
||||
expect(ret).to.eql([g, 'a', { translator: 't', Promise: 'P' }]);
|
||||
});
|
||||
|
||||
@@ -11,9 +11,11 @@ describe('qae', () => {
|
||||
});
|
||||
|
||||
it('should provide properties', () => {
|
||||
expect(qae({
|
||||
properties: { p: 'p' },
|
||||
}).properties).to.eql({ p: 'p' });
|
||||
expect(
|
||||
qae({
|
||||
properties: { p: 'p' },
|
||||
}).properties
|
||||
).to.eql({ p: 'p' });
|
||||
});
|
||||
|
||||
it('should map target defaults', () => {
|
||||
@@ -34,24 +36,26 @@ describe('qae', () => {
|
||||
it('should map provided data', () => {
|
||||
const t = qae({
|
||||
data: {
|
||||
targets: [{
|
||||
path: 'qhc',
|
||||
dimensions: {
|
||||
min: () => 3,
|
||||
max: () => 7,
|
||||
add: () => 'a',
|
||||
description: () => 'Slice',
|
||||
move: () => 'c',
|
||||
replace: () => 'd',
|
||||
targets: [
|
||||
{
|
||||
path: 'qhc',
|
||||
dimensions: {
|
||||
min: () => 3,
|
||||
max: () => 7,
|
||||
add: () => 'a',
|
||||
description: () => 'Slice',
|
||||
move: () => 'c',
|
||||
replace: () => 'd',
|
||||
},
|
||||
measures: {
|
||||
min: 2,
|
||||
max: 4,
|
||||
add: () => 'b',
|
||||
description: () => 'Angle',
|
||||
remove: () => 'e',
|
||||
},
|
||||
},
|
||||
measures: {
|
||||
min: 2,
|
||||
max: 4,
|
||||
add: () => 'b',
|
||||
description: () => 'Angle',
|
||||
remove: () => 'e',
|
||||
},
|
||||
}],
|
||||
],
|
||||
},
|
||||
}).data.targets[0];
|
||||
expect(t.path).to.eql('qhc');
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import EventEmitter from 'node-event-emitter';
|
||||
|
||||
const mixin = (obj) => {
|
||||
const mixin = obj => {
|
||||
/* eslint no-param-reassign: 0 */
|
||||
Object.keys(EventEmitter.prototype).forEach((key) => {
|
||||
Object.keys(EventEmitter.prototype).forEach(key => {
|
||||
obj[key] = EventEmitter.prototype[key];
|
||||
});
|
||||
EventEmitter.init(obj);
|
||||
return obj;
|
||||
};
|
||||
|
||||
const actionWrapper = (component) => (item) => {
|
||||
const actionWrapper = component => item => {
|
||||
const wrapped = mixin({
|
||||
...item,
|
||||
action() {
|
||||
@@ -24,29 +24,29 @@ const actionWrapper = (component) => (item) => {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
active: typeof item.active === 'function' ? function active() {
|
||||
return item.active.call(wrapped, component);
|
||||
} : undefined,
|
||||
active:
|
||||
typeof item.active === 'function'
|
||||
? function active() {
|
||||
return item.active.call(wrapped, component);
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
|
||||
return wrapped;
|
||||
};
|
||||
|
||||
export default function ({
|
||||
sn,
|
||||
component,
|
||||
}) {
|
||||
export default function({ sn, component }) {
|
||||
const actions = {};
|
||||
const selectionToolbarItems = [];
|
||||
const w = actionWrapper(component);
|
||||
((sn.definition.selectionToolbar || {}).items || []).forEach((item) => {
|
||||
((sn.definition.selectionToolbar || {}).items || []).forEach(item => {
|
||||
const wrapped = w(item);
|
||||
// TODO - check if key exists
|
||||
actions[item.key] = wrapped;
|
||||
selectionToolbarItems.push(wrapped);
|
||||
});
|
||||
|
||||
(sn.definition.actions || []).forEach((item) => {
|
||||
(sn.definition.actions || []).forEach(item => {
|
||||
const wrapped = w(item);
|
||||
// TODO - check if key exists
|
||||
actions[item.key] = wrapped;
|
||||
|
||||
@@ -18,14 +18,14 @@ const defaultComponent = {
|
||||
getViewState: () => {},
|
||||
|
||||
// temporary
|
||||
setSnapshotData: (snapshot) => Promise.resolve(snapshot),
|
||||
setSnapshotData: snapshot => Promise.resolve(snapshot),
|
||||
};
|
||||
|
||||
const reservedKeys = Object.keys(defaultComponent);
|
||||
|
||||
const mixin = (obj) => {
|
||||
const mixin = obj => {
|
||||
/* eslint no-param-reassign: 0 */
|
||||
Object.keys(EventEmitter.prototype).forEach((key) => {
|
||||
Object.keys(EventEmitter.prototype).forEach(key => {
|
||||
obj[key] = EventEmitter.prototype[key];
|
||||
});
|
||||
EventEmitter.init(obj);
|
||||
@@ -45,7 +45,7 @@ export default function create(sn, opts) {
|
||||
},
|
||||
};
|
||||
|
||||
Object.keys(sn.component || {}).forEach((key) => {
|
||||
Object.keys(sn.component || {}).forEach(key => {
|
||||
if (reservedKeys.indexOf(key) !== -1) {
|
||||
componentInstance[key] = sn.component[key].bind(userInstance);
|
||||
} else {
|
||||
|
||||
@@ -27,7 +27,7 @@ export default function generatorFn(UserSN, env) {
|
||||
definition: {},
|
||||
};
|
||||
|
||||
Object.keys(sn).forEach((key) => {
|
||||
Object.keys(sn).forEach(key => {
|
||||
if (!generator[key]) {
|
||||
generator.definition[key] = sn[key];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export default {
|
||||
get(str/* , args */) {
|
||||
get(str /* , args */) {
|
||||
return `$$$${str}$$$`;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -54,10 +54,8 @@ export {
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
ListItemSecondaryAction,
|
||||
|
||||
FormGroup,
|
||||
FormControlLabel,
|
||||
Switch,
|
||||
|
||||
TextField,
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@ import SvgIcon from './SvgIcon';
|
||||
|
||||
export default function SelectionsBack() {
|
||||
return SvgIcon({
|
||||
d: 'M6,15.5 L6,15.5 C6,15.2238576 6.22385763,15 6.5,15 L9.5,15 C9.77614237,15 10,15.2238576 10,15.5 L10,15.5 C10,15.7761424 9.77614237,16 9.5,16 L6.5,16 C6.22385763,16 6,15.7761424 6,15.5 Z M1,13.5 L1,14.5 C1,14.7761424 1.22385763,15 1.5,15 L2.5,15 C2.77614237,15 3,15.2238576 3,15.5 L3,15.5 C3,15.7761424 2.77614237,16 2.5,16 L1,16 C0.44771525,16 6.76353751e-17,15.5522847 0,15 L0,13.5 C-3.38176876e-17,13.2238576 0.223857625,13 0.5,13 L0.5,13 C0.776142375,13 1,13.2238576 1,13.5 Z M1,6.5 L1,9.5 C1,9.77614237 0.776142375,10 0.5,10 L0.5,10 C0.223857625,10 3.38176876e-17,9.77614237 0,9.5 L0,6.5 C-3.38176876e-17,6.22385763 0.223857625,6 0.5,6 L0.5,6 C0.776142375,6 1,6.22385763 1,6.5 Z M0,2.5 L0,1 C-6.76353751e-17,0.44771525 0.44771525,1.01453063e-16 1,0 L2.5,0 C2.77614237,-5.07265313e-17 3,0.223857625 3,0.5 L3,0.5 C3,0.776142375 2.77614237,1 2.5,1 L1.5,1 C1.22385763,1 1,1.22385763 1,1.5 L1,2.5 C1,2.77614237 0.776142375,3 0.5,3 L0.5,3 C0.223857625,3 3.38176876e-17,2.77614237 0,2.5 Z M6,0.5 L6,0.5 C6,0.223857625 6.22385763,5.07265313e-17 6.5,0 L9.5,0 C9.77614237,-5.07265313e-17 10,0.223857625 10,0.5 L10,0.5 C10,0.776142375 9.77614237,1 9.5,1 L6.5,1 C6.22385763,1 6,0.776142375 6,0.5 Z M15,2.5 L15,1.5 C15,1.22385763 14.7761424,1 14.5,1 L13.5,1 C13.2238576,1 13,0.776142375 13,0.5 L13,0.5 C13,0.223857625 13.2238576,5.07265313e-17 13.5,0 L15,0 C15.5522847,-1.01453063e-16 16,0.44771525 16,1 L16,2.5 C16,2.77614237 15.7761424,3 15.5,3 L15.5,3 C15.2238576,3 15,2.77614237 15,2.5 Z M9.1661442,6.1661442 C10.7210031,4.61128527 13.2789969,4.61128527 14.8338558,6.1661442 C16.3887147,7.72100313 16.3887147,10.2789969 14.8338558,11.8338558 C13.2789969,13.3887147 10.7210031,13.3887147 9.1661442,11.8338558 C7.61128527,10.2789969 7.61128527,7.77115987 9.1661442,6.1661442 Z M14.1316614,7.72100313 C14.3322884,7.52037618 14.3824451,7.169279 14.1316614,6.9184953 C13.8808777,6.6677116 13.5297806,6.71786834 13.3291536,6.9184953 L12.0250784,8.22257053 L10.7210031,6.9184953 C10.5203762,6.6677116 10.1191223,6.6677116 9.9184953,6.9184953 C9.6677116,7.11912226 9.6677116,7.52037618 9.9184953,7.72100313 L11.2225705,9.02507837 L9.9184953,10.3291536 C9.6677116,10.5297806 9.6677116,10.8808777 9.9184953,11.1316614 C10.169279,11.3824451 10.5203762,11.3824451 10.7210031,11.1316614 L12.0250784,9.82758621 L13.3291536,11.1316614 C13.5297806,11.3824451 13.8808777,11.3824451 14.1316614,11.1316614 C14.3322884,10.9310345 14.3824451,10.5297806 14.1316614,10.3291536 L12.8275862,9.02507837 L14.1316614,7.72100313 Z',
|
||||
d:
|
||||
'M6,15.5 L6,15.5 C6,15.2238576 6.22385763,15 6.5,15 L9.5,15 C9.77614237,15 10,15.2238576 10,15.5 L10,15.5 C10,15.7761424 9.77614237,16 9.5,16 L6.5,16 C6.22385763,16 6,15.7761424 6,15.5 Z M1,13.5 L1,14.5 C1,14.7761424 1.22385763,15 1.5,15 L2.5,15 C2.77614237,15 3,15.2238576 3,15.5 L3,15.5 C3,15.7761424 2.77614237,16 2.5,16 L1,16 C0.44771525,16 6.76353751e-17,15.5522847 0,15 L0,13.5 C-3.38176876e-17,13.2238576 0.223857625,13 0.5,13 L0.5,13 C0.776142375,13 1,13.2238576 1,13.5 Z M1,6.5 L1,9.5 C1,9.77614237 0.776142375,10 0.5,10 L0.5,10 C0.223857625,10 3.38176876e-17,9.77614237 0,9.5 L0,6.5 C-3.38176876e-17,6.22385763 0.223857625,6 0.5,6 L0.5,6 C0.776142375,6 1,6.22385763 1,6.5 Z M0,2.5 L0,1 C-6.76353751e-17,0.44771525 0.44771525,1.01453063e-16 1,0 L2.5,0 C2.77614237,-5.07265313e-17 3,0.223857625 3,0.5 L3,0.5 C3,0.776142375 2.77614237,1 2.5,1 L1.5,1 C1.22385763,1 1,1.22385763 1,1.5 L1,2.5 C1,2.77614237 0.776142375,3 0.5,3 L0.5,3 C0.223857625,3 3.38176876e-17,2.77614237 0,2.5 Z M6,0.5 L6,0.5 C6,0.223857625 6.22385763,5.07265313e-17 6.5,0 L9.5,0 C9.77614237,-5.07265313e-17 10,0.223857625 10,0.5 L10,0.5 C10,0.776142375 9.77614237,1 9.5,1 L6.5,1 C6.22385763,1 6,0.776142375 6,0.5 Z M15,2.5 L15,1.5 C15,1.22385763 14.7761424,1 14.5,1 L13.5,1 C13.2238576,1 13,0.776142375 13,0.5 L13,0.5 C13,0.223857625 13.2238576,5.07265313e-17 13.5,0 L15,0 C15.5522847,-1.01453063e-16 16,0.44771525 16,1 L16,2.5 C16,2.77614237 15.7761424,3 15.5,3 L15.5,3 C15.2238576,3 15,2.77614237 15,2.5 Z M9.1661442,6.1661442 C10.7210031,4.61128527 13.2789969,4.61128527 14.8338558,6.1661442 C16.3887147,7.72100313 16.3887147,10.2789969 14.8338558,11.8338558 C13.2789969,13.3887147 10.7210031,13.3887147 9.1661442,11.8338558 C7.61128527,10.2789969 7.61128527,7.77115987 9.1661442,6.1661442 Z M14.1316614,7.72100313 C14.3322884,7.52037618 14.3824451,7.169279 14.1316614,6.9184953 C13.8808777,6.6677116 13.5297806,6.71786834 13.3291536,6.9184953 L12.0250784,8.22257053 L10.7210031,6.9184953 C10.5203762,6.6677116 10.1191223,6.6677116 9.9184953,6.9184953 C9.6677116,7.11912226 9.6677116,7.52037618 9.9184953,7.72100313 L11.2225705,9.02507837 L9.9184953,10.3291536 C9.6677116,10.5297806 9.6677116,10.8808777 9.9184953,11.1316614 C10.169279,11.3824451 10.5203762,11.3824451 10.7210031,11.1316614 L12.0250784,9.82758621 L13.3291536,11.1316614 C13.5297806,11.3824451 13.8808777,11.3824451 14.1316614,11.1316614 C14.3322884,10.9310345 14.3824451,10.5297806 14.1316614,10.3291536 L12.8275862,9.02507837 L14.1316614,7.72100313 Z',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import SvgIcon from './SvgIcon';
|
||||
|
||||
export default function Close() {
|
||||
return SvgIcon({
|
||||
d: 'M9.34535242,8 L13.3273238,11.9819714 C13.6988326,12.3534802 13.6988326,12.955815 13.3273238,13.3273238 C12.955815,13.6988326 12.3534802,13.6988326 11.9819714,13.3273238 L8,9.34535242 L4.01802863,13.3273238 C3.64651982,13.6988326 3.04418502,13.6988326 2.67267621,13.3273238 C2.3011674,12.955815 2.3011674,12.3534802 2.67267621,11.9819714 L6.65464758,8 L2.67267621,4.01802863 C2.3011674,3.64651982 2.3011674,3.04418502 2.67267621,2.67267621 C3.04418502,2.3011674 3.64651982,2.3011674 4.01802863,2.67267621 L8,6.65464758 L11.9819714,2.67267621 C12.3534802,2.3011674 12.955815,2.3011674 13.3273238,2.67267621 C13.6988326,3.04418502 13.6988326,3.64651982 13.3273238,4.01802863 L9.34535242,8 Z',
|
||||
d:
|
||||
'M9.34535242,8 L13.3273238,11.9819714 C13.6988326,12.3534802 13.6988326,12.955815 13.3273238,13.3273238 C12.955815,13.6988326 12.3534802,13.6988326 11.9819714,13.3273238 L8,9.34535242 L4.01802863,13.3273238 C3.64651982,13.6988326 3.04418502,13.6988326 2.67267621,13.3273238 C2.3011674,12.955815 2.3011674,12.3534802 2.67267621,11.9819714 L6.65464758,8 L2.67267621,4.01802863 C2.3011674,3.64651982 2.3011674,3.04418502 2.67267621,2.67267621 C3.04418502,2.3011674 3.64651982,2.3011674 4.01802863,2.67267621 L8,6.65464758 L11.9819714,2.67267621 C12.3534802,2.3011674 12.955815,2.3011674 13.3273238,2.67267621 C13.6988326,3.04418502 13.6988326,3.64651982 13.3273238,4.01802863 L9.34535242,8 Z',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import SvgIcon from './SvgIcon';
|
||||
|
||||
export default function Lasso() {
|
||||
return SvgIcon({
|
||||
d: 'M15.9488039,5.20769129 C16.0487326,6.70662306 15.3492311,8.30548361 14.050157,9.30477145 C12.651154,10.5039169 10.8524359,10.8037032 8.85386017,10.4039881 L7.3549284,10.0042729 L5.75606786,9.70448659 C5.75606786,9.90434416 5.65613907,10.0042729 5.4562815,10.2041305 C5.05656637,10.6038456 4.55692244,10.8037032 4.05727852,10.8037032 C3.75749217,10.8037032 3.45770582,10.7037744 3.15791946,10.6038456 C3.05799068,10.903632 3.15791946,11.2034184 3.45770582,11.7030623 C5.05656637,14.0014243 3.85742095,15.9000712 3.75749217,16 L2.2585604,15.3004985 C2.2585604,15.2005697 2.95806189,14.0014243 1.95877405,12.6024213 C1.6589877,12.0028486 1.15934378,11.0035608 1.55905891,10.0042729 C1.6589877,9.80441537 1.75891648,9.6045578 1.95877405,9.40470024 C1.6589877,8.90505631 1.55905891,8.30548361 1.85884527,7.7059109 C1.55905891,7.40612455 1.25927256,7.1063382 1.15934378,6.70662306 C0.859557424,5.90719279 0.959486209,4.5081898 1.6589877,3.30904439 C1.95877405,2.6095429 2.55834676,2.0099702 3.15791946,1.51032628 C3.95734974,0.91075357 4.95663758,0.610967217 6.15578299,0.311180864 C9.05371774,-0.388320626 11.9516525,0.111323295 13.9502282,1.61025506 C15.1493736,2.50961412 15.8488751,3.80868831 15.9488039,5.20769129 Z M13.0508691,8.10562604 C13.8502994,7.40612455 14.3499433,6.40683671 14.3499433,5.30762008 C14.2500145,4.20840345 13.550513,3.40897318 12.9509403,2.90932926 C12.1515101,2.40968533 11.252151,2.0099702 10.1529344,1.81011263 C8.95378895,1.61025506 7.75464354,1.71018384 6.45556935,1.91004141 C4.75678001,2.30975655 3.65756338,3.00925804 3.05799068,4.10847467 C2.55834676,5.00783373 2.65827554,5.90719279 2.75820433,6.20697914 C2.75820433,6.30690792 2.85813311,6.40683671 3.05799068,6.40683671 C3.15791946,6.40683671 3.25784825,6.40683671 3.35777703,6.40683671 C3.45770582,6.40683671 3.45770582,6.40683671 3.45770582,6.40683671 L3.5576346,6.40683671 L3.65756338,6.40683671 C4.65685123,6.40683671 5.4562815,6.90648063 5.85599664,7.80583969 L5.85599664,8.00569726 C6.35564056,8.10562604 7.05514205,8.30548361 7.75464354,8.50534118 L9.25357531,8.90505631 C10.0530056,9.0049851 10.7525071,9.0049851 11.4520086,8.80512753 C12.0515813,8.70519875 12.5512252,8.40541239 13.0508691,8.10562604 Z',
|
||||
d:
|
||||
'M15.9488039,5.20769129 C16.0487326,6.70662306 15.3492311,8.30548361 14.050157,9.30477145 C12.651154,10.5039169 10.8524359,10.8037032 8.85386017,10.4039881 L7.3549284,10.0042729 L5.75606786,9.70448659 C5.75606786,9.90434416 5.65613907,10.0042729 5.4562815,10.2041305 C5.05656637,10.6038456 4.55692244,10.8037032 4.05727852,10.8037032 C3.75749217,10.8037032 3.45770582,10.7037744 3.15791946,10.6038456 C3.05799068,10.903632 3.15791946,11.2034184 3.45770582,11.7030623 C5.05656637,14.0014243 3.85742095,15.9000712 3.75749217,16 L2.2585604,15.3004985 C2.2585604,15.2005697 2.95806189,14.0014243 1.95877405,12.6024213 C1.6589877,12.0028486 1.15934378,11.0035608 1.55905891,10.0042729 C1.6589877,9.80441537 1.75891648,9.6045578 1.95877405,9.40470024 C1.6589877,8.90505631 1.55905891,8.30548361 1.85884527,7.7059109 C1.55905891,7.40612455 1.25927256,7.1063382 1.15934378,6.70662306 C0.859557424,5.90719279 0.959486209,4.5081898 1.6589877,3.30904439 C1.95877405,2.6095429 2.55834676,2.0099702 3.15791946,1.51032628 C3.95734974,0.91075357 4.95663758,0.610967217 6.15578299,0.311180864 C9.05371774,-0.388320626 11.9516525,0.111323295 13.9502282,1.61025506 C15.1493736,2.50961412 15.8488751,3.80868831 15.9488039,5.20769129 Z M13.0508691,8.10562604 C13.8502994,7.40612455 14.3499433,6.40683671 14.3499433,5.30762008 C14.2500145,4.20840345 13.550513,3.40897318 12.9509403,2.90932926 C12.1515101,2.40968533 11.252151,2.0099702 10.1529344,1.81011263 C8.95378895,1.61025506 7.75464354,1.71018384 6.45556935,1.91004141 C4.75678001,2.30975655 3.65756338,3.00925804 3.05799068,4.10847467 C2.55834676,5.00783373 2.65827554,5.90719279 2.75820433,6.20697914 C2.75820433,6.30690792 2.85813311,6.40683671 3.05799068,6.40683671 C3.15791946,6.40683671 3.25784825,6.40683671 3.35777703,6.40683671 C3.45770582,6.40683671 3.45770582,6.40683671 3.45770582,6.40683671 L3.5576346,6.40683671 L3.65756338,6.40683671 C4.65685123,6.40683671 5.4562815,6.90648063 5.85599664,7.80583969 L5.85599664,8.00569726 C6.35564056,8.10562604 7.05514205,8.30548361 7.75464354,8.50534118 L9.25357531,8.90505631 C10.0530056,9.0049851 10.7525071,9.0049851 11.4520086,8.80512753 C12.0515813,8.70519875 12.5512252,8.40541239 13.0508691,8.10562604 Z',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import SvgIcon from './SvgIcon';
|
||||
export default function Lock(props = {}) {
|
||||
return SvgIcon({
|
||||
...props,
|
||||
d: 'M13,7 L8,7 L13,7 L13,4.98151367 C13,2.23029964 10.7614237,0 8,0 C5.23857625,0 3,2.23029964 3,4.98151367 L3,7 L3.75,7 L3,7 L4.5,7 L4.5,5.33193359 C4.5,3.21561511 5.54860291,1.5 8,1.5 C10.4513971,1.5 11.5,3.21561511 11.5,5.33193359 L11.5,7 L12.25,7 L3,7 C2.44771525,7 2,7.44771525 2,8 L2,15 C2,15.5522847 2.44771525,16 3,16 L13,16 C13.5522847,16 14,15.5522847 14,15 L14,8 C14,7.44771525 13.5522847,7 13,7 L3,7 L13,7 Z',
|
||||
d:
|
||||
'M13,7 L8,7 L13,7 L13,4.98151367 C13,2.23029964 10.7614237,0 8,0 C5.23857625,0 3,2.23029964 3,4.98151367 L3,7 L3.75,7 L3,7 L4.5,7 L4.5,5.33193359 C4.5,3.21561511 5.54860291,1.5 8,1.5 C10.4513971,1.5 11.5,3.21561511 11.5,5.33193359 L11.5,7 L12.25,7 L3,7 C2.44771525,7 2,7.44771525 2,8 L2,15 C2,15.5522847 2.44771525,16 3,16 L13,16 C13.5522847,16 14,15.5522847 14,15 L14,8 C14,7.44771525 13.5522847,7 13,7 L3,7 L13,7 Z',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import SvgIcon from './SvgIcon';
|
||||
|
||||
export default function Remove() {
|
||||
return SvgIcon({
|
||||
d: 'M9.41421356,8 L11.8890873,5.52512627 C12.065864,5.34834957 12.0305087,4.95944084 11.8183766,4.74730881 L11.2526912,4.18162338 C11.0405592,3.96949135 10.6516504,3.93413601 10.4748737,4.1109127 L8,6.58578644 L5.52512627,4.1109127 C5.34834957,3.93413601 4.95944084,3.96949135 4.74730881,4.18162338 L4.25233406,4.67659813 C3.96949135,4.95944084 3.93413601,5.34834957 4.1109127,5.52512627 L6.58578644,8 L4.1109127,10.4748737 C3.93413601,10.6516504 3.96949135,11.0405592 4.18162338,11.2526912 L4.67659813,11.7476659 C4.95944084,12.0305087 5.34834957,12.065864 5.52512627,11.8890873 L8,9.41421356 L10.4748737,11.8890873 C10.6516504,12.065864 11.0405592,12.0305087 11.2526912,11.8183766 L11.8183766,11.2526912 C12.0305087,11.0405592 12.065864,10.6516504 11.8890873,10.4748737 L9.41421356,8 Z M8,0 C12.4,0 16,3.6 16,8 C16,12.4 12.4,16 8,16 C3.6,16 0,12.4 0,8 C0,3.6 3.6,0 8,0 Z',
|
||||
d:
|
||||
'M9.41421356,8 L11.8890873,5.52512627 C12.065864,5.34834957 12.0305087,4.95944084 11.8183766,4.74730881 L11.2526912,4.18162338 C11.0405592,3.96949135 10.6516504,3.93413601 10.4748737,4.1109127 L8,6.58578644 L5.52512627,4.1109127 C5.34834957,3.93413601 4.95944084,3.96949135 4.74730881,4.18162338 L4.25233406,4.67659813 C3.96949135,4.95944084 3.93413601,5.34834957 4.1109127,5.52512627 L6.58578644,8 L4.1109127,10.4748737 C3.93413601,10.6516504 3.96949135,11.0405592 4.18162338,11.2526912 L4.67659813,11.7476659 C4.95944084,12.0305087 5.34834957,12.065864 5.52512627,11.8890873 L8,9.41421356 L10.4748737,11.8890873 C10.6516504,12.065864 11.0405592,12.0305087 11.2526912,11.8183766 L11.8183766,11.2526912 C12.0305087,11.0405592 12.065864,10.6516504 11.8890873,10.4748737 L9.41421356,8 Z M8,0 C12.4,0 16,3.6 16,8 C16,12.4 12.4,16 8,16 C3.6,16 0,12.4 0,8 C0,3.6 3.6,0 8,0 Z',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import SvgIcon from './SvgIcon';
|
||||
|
||||
export default function SelectionsBack() {
|
||||
return SvgIcon({
|
||||
d: 'M10,15.5 C10,15.7761424 9.77614237,16 9.5,16 L6.5,16 C6.22385763,16 6,15.7761424 6,15.5 C6,15.2238576 6.22385763,15 6.5,15 L9.5,15 C9.77614237,15 10,15.2238576 10,15.5 Z M15,13.5 C15,13.2238576 15.2238576,13 15.5,13 C15.7761424,13 16,13.2238576 16,13.5 L16,15 C16,15.5522847 15.5522847,16 15,16 L13.5,16 C13.2238576,16 13,15.7761424 13,15.5 C13,15.2238576 13.2238576,15 13.5,15 L14.5,15 C14.7761424,15 15,14.7761424 15,14.5 L15,13.5 Z M15,6.5 C15,6.22385763 15.2238576,6 15.5,6 C15.7761424,6 16,6.22385763 16,6.5 L16,9.5 C16,9.77614237 15.7761424,10 15.5,10 C15.2238576,10 15,9.77614237 15,9.5 L15,6.5 Z M16,2.5 C16,2.77614237 15.7761424,3 15.5,3 C15.2238576,3 15,2.77614237 15,2.5 L15,1.5 C15,1.22385763 14.7761424,1 14.5,1 L13.5,1 C13.2238576,1 13,0.776142375 13,0.5 C13,0.223857625 13.2238576,-5.07265313e-17 13.5,0 L15,0 C15.5522847,1.01453063e-16 16,0.44771525 16,1 L16,2.5 Z M10,0.5 C10,0.776142375 9.77614237,1 9.5,1 L6.5,1 C6.22385763,1 6,0.776142375 6,0.5 C6,0.223857625 6.22385763,-5.07265313e-17 6.5,0 L9.5,0 C9.77614237,5.07265313e-17 10,0.223857625 10,0.5 Z M1,2.5 C1,2.77614237 0.776142375,3 0.5,3 C0.223857625,3 5.18696197e-13,2.77614237 5.18696197e-13,2.5 L5.18696197e-13,1 C5.18696197e-13,0.44771525 0.44771525,-1.01453063e-16 1,0 L2.5,0 C2.77614237,5.07265313e-17 3,0.223857625 3,0.5 C3,0.776142375 2.77614237,1 2.5,1 L1.5,1 C1.22385763,1 1,1.22385763 1,1.5 L1,2.5 Z M1,13.5 L1,14.5 C1,14.7761424 1.22385763,15 1.5,15 L2.5,15 C2.77614237,15 3,15.2238576 3,15.5 C3,15.7761424 2.77614237,16 2.5,16 L1,16 C0.44771525,16 5.18696197e-13,15.5522847 5.18696197e-13,15 L5.18696197e-13,13.5 C5.18696197e-13,13.2238576 0.223857625,13 0.5,13 C0.776142375,13 1,13.2238576 1,13.5 Z M4,7 C7.49095643,7 10,10.1337595 10,12.1872632 C10,12.1872632 8.16051135,9.86624054 4,10 L4,12 C4,12 2.66666667,10.8333333 -1.0658141e-14,8.5 C-2.59348099e-13,8.5 1.33333333,7.33333333 4,5 C4,5 4,5.66666667 4,7 Z',
|
||||
d:
|
||||
'M10,15.5 C10,15.7761424 9.77614237,16 9.5,16 L6.5,16 C6.22385763,16 6,15.7761424 6,15.5 C6,15.2238576 6.22385763,15 6.5,15 L9.5,15 C9.77614237,15 10,15.2238576 10,15.5 Z M15,13.5 C15,13.2238576 15.2238576,13 15.5,13 C15.7761424,13 16,13.2238576 16,13.5 L16,15 C16,15.5522847 15.5522847,16 15,16 L13.5,16 C13.2238576,16 13,15.7761424 13,15.5 C13,15.2238576 13.2238576,15 13.5,15 L14.5,15 C14.7761424,15 15,14.7761424 15,14.5 L15,13.5 Z M15,6.5 C15,6.22385763 15.2238576,6 15.5,6 C15.7761424,6 16,6.22385763 16,6.5 L16,9.5 C16,9.77614237 15.7761424,10 15.5,10 C15.2238576,10 15,9.77614237 15,9.5 L15,6.5 Z M16,2.5 C16,2.77614237 15.7761424,3 15.5,3 C15.2238576,3 15,2.77614237 15,2.5 L15,1.5 C15,1.22385763 14.7761424,1 14.5,1 L13.5,1 C13.2238576,1 13,0.776142375 13,0.5 C13,0.223857625 13.2238576,-5.07265313e-17 13.5,0 L15,0 C15.5522847,1.01453063e-16 16,0.44771525 16,1 L16,2.5 Z M10,0.5 C10,0.776142375 9.77614237,1 9.5,1 L6.5,1 C6.22385763,1 6,0.776142375 6,0.5 C6,0.223857625 6.22385763,-5.07265313e-17 6.5,0 L9.5,0 C9.77614237,5.07265313e-17 10,0.223857625 10,0.5 Z M1,2.5 C1,2.77614237 0.776142375,3 0.5,3 C0.223857625,3 5.18696197e-13,2.77614237 5.18696197e-13,2.5 L5.18696197e-13,1 C5.18696197e-13,0.44771525 0.44771525,-1.01453063e-16 1,0 L2.5,0 C2.77614237,5.07265313e-17 3,0.223857625 3,0.5 C3,0.776142375 2.77614237,1 2.5,1 L1.5,1 C1.22385763,1 1,1.22385763 1,1.5 L1,2.5 Z M1,13.5 L1,14.5 C1,14.7761424 1.22385763,15 1.5,15 L2.5,15 C2.77614237,15 3,15.2238576 3,15.5 C3,15.7761424 2.77614237,16 2.5,16 L1,16 C0.44771525,16 5.18696197e-13,15.5522847 5.18696197e-13,15 L5.18696197e-13,13.5 C5.18696197e-13,13.2238576 0.223857625,13 0.5,13 C0.776142375,13 1,13.2238576 1,13.5 Z M4,7 C7.49095643,7 10,10.1337595 10,12.1872632 C10,12.1872632 8.16051135,9.86624054 4,10 L4,12 C4,12 2.66666667,10.8333333 -1.0658141e-14,8.5 C-2.59348099e-13,8.5 1.33333333,7.33333333 4,5 C4,5 4,5.66666667 4,7 Z',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import SvgIcon from './SvgIcon';
|
||||
|
||||
export default function SelectionsForward() {
|
||||
return SvgIcon({
|
||||
d: 'M6,15.5 L6,15.5 C6,15.2238576 6.22385763,15 6.5,15 L9.5,15 C9.77614237,15 10,15.2238576 10,15.5 L10,15.5 C10,15.7761424 9.77614237,16 9.5,16 L6.5,16 C6.22385763,16 6,15.7761424 6,15.5 Z M1,13.5 L1,14.5 C1,14.7761424 1.22385763,15 1.5,15 L2.5,15 C2.77614237,15 3,15.2238576 3,15.5 L3,15.5 C3,15.7761424 2.77614237,16 2.5,16 L1,16 C0.44771525,16 6.76353751e-17,15.5522847 0,15 L0,13.5 C-3.38176876e-17,13.2238576 0.223857625,13 0.5,13 L0.5,13 C0.776142375,13 1,13.2238576 1,13.5 Z M1,6.5 L1,9.5 C1,9.77614237 0.776142375,10 0.5,10 L0.5,10 C0.223857625,10 3.38176876e-17,9.77614237 0,9.5 L0,6.5 C-3.38176876e-17,6.22385763 0.223857625,6 0.5,6 L0.5,6 C0.776142375,6 1,6.22385763 1,6.5 Z M0,2.5 L0,1 C-6.76353751e-17,0.44771525 0.44771525,1.01453063e-16 1,0 L2.5,0 C2.77614237,-5.07265313e-17 3,0.223857625 3,0.5 L3,0.5 C3,0.776142375 2.77614237,1 2.5,1 L1.5,1 C1.22385763,1 1,1.22385763 1,1.5 L1,2.5 C1,2.77614237 0.776142375,3 0.5,3 L0.5,3 C0.223857625,3 3.38176876e-17,2.77614237 0,2.5 Z M6,0.5 L6,0.5 C6,0.223857625 6.22385763,5.07265313e-17 6.5,0 L9.5,0 C9.77614237,-5.07265313e-17 10,0.223857625 10,0.5 L10,0.5 C10,0.776142375 9.77614237,1 9.5,1 L6.5,1 C6.22385763,1 6,0.776142375 6,0.5 Z M15,2.5 L15,1.5 C15,1.22385763 14.7761424,1 14.5,1 L13.5,1 C13.2238576,1 13,0.776142375 13,0.5 L13,0.5 C13,0.223857625 13.2238576,5.07265313e-17 13.5,0 L15,0 C15.5522847,-1.01453063e-16 16,0.44771525 16,1 L16,2.5 C16,2.77614237 15.7761424,3 15.5,3 L15.5,3 C15.2238576,3 15,2.77614237 15,2.5 Z M15,13.5 C15,13.2238576 15.2238576,13 15.5,13 C15.7761424,13 16,13.2238576 16,13.5 L16,15 C16,15.5522847 15.5522847,16 15,16 L13.5,16 C13.2238576,16 13,15.7761424 13,15.5 C13,15.2238576 13.2238576,15 13.5,15 L14.5,15 C14.7761424,15 15,14.7761424 15,14.5 L15,13.5 Z M12,7 C12,5.66666667 12,5 12,5 C14.6666667,7.33333333 16,8.5 16,8.5 C13.3333333,10.8333333 12,12 12,12 L12,10 C7.83948865,9.86624054 6,12.1872632 6,12.1872632 C6,10.1337595 8.50904357,7 12,7 Z',
|
||||
d:
|
||||
'M6,15.5 L6,15.5 C6,15.2238576 6.22385763,15 6.5,15 L9.5,15 C9.77614237,15 10,15.2238576 10,15.5 L10,15.5 C10,15.7761424 9.77614237,16 9.5,16 L6.5,16 C6.22385763,16 6,15.7761424 6,15.5 Z M1,13.5 L1,14.5 C1,14.7761424 1.22385763,15 1.5,15 L2.5,15 C2.77614237,15 3,15.2238576 3,15.5 L3,15.5 C3,15.7761424 2.77614237,16 2.5,16 L1,16 C0.44771525,16 6.76353751e-17,15.5522847 0,15 L0,13.5 C-3.38176876e-17,13.2238576 0.223857625,13 0.5,13 L0.5,13 C0.776142375,13 1,13.2238576 1,13.5 Z M1,6.5 L1,9.5 C1,9.77614237 0.776142375,10 0.5,10 L0.5,10 C0.223857625,10 3.38176876e-17,9.77614237 0,9.5 L0,6.5 C-3.38176876e-17,6.22385763 0.223857625,6 0.5,6 L0.5,6 C0.776142375,6 1,6.22385763 1,6.5 Z M0,2.5 L0,1 C-6.76353751e-17,0.44771525 0.44771525,1.01453063e-16 1,0 L2.5,0 C2.77614237,-5.07265313e-17 3,0.223857625 3,0.5 L3,0.5 C3,0.776142375 2.77614237,1 2.5,1 L1.5,1 C1.22385763,1 1,1.22385763 1,1.5 L1,2.5 C1,2.77614237 0.776142375,3 0.5,3 L0.5,3 C0.223857625,3 3.38176876e-17,2.77614237 0,2.5 Z M6,0.5 L6,0.5 C6,0.223857625 6.22385763,5.07265313e-17 6.5,0 L9.5,0 C9.77614237,-5.07265313e-17 10,0.223857625 10,0.5 L10,0.5 C10,0.776142375 9.77614237,1 9.5,1 L6.5,1 C6.22385763,1 6,0.776142375 6,0.5 Z M15,2.5 L15,1.5 C15,1.22385763 14.7761424,1 14.5,1 L13.5,1 C13.2238576,1 13,0.776142375 13,0.5 L13,0.5 C13,0.223857625 13.2238576,5.07265313e-17 13.5,0 L15,0 C15.5522847,-1.01453063e-16 16,0.44771525 16,1 L16,2.5 C16,2.77614237 15.7761424,3 15.5,3 L15.5,3 C15.2238576,3 15,2.77614237 15,2.5 Z M15,13.5 C15,13.2238576 15.2238576,13 15.5,13 C15.7761424,13 16,13.2238576 16,13.5 L16,15 C16,15.5522847 15.5522847,16 15,16 L13.5,16 C13.2238576,16 13,15.7761424 13,15.5 C13,15.2238576 13.2238576,15 13.5,15 L14.5,15 C14.7761424,15 15,14.7761424 15,14.5 L15,13.5 Z M12,7 C12,5.66666667 12,5 12,5 C14.6666667,7.33333333 16,8.5 16,8.5 C13.3333333,10.8333333 12,12 12,12 L12,10 C7.83948865,9.86624054 6,12.1872632 6,12.1872632 C6,10.1337595 8.50904357,7 12,7 Z',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,11 +10,7 @@ function getFontSize(size) {
|
||||
return '16px';
|
||||
}
|
||||
|
||||
export default function SvgIcon({
|
||||
d,
|
||||
size,
|
||||
style = {},
|
||||
}) {
|
||||
export default function SvgIcon({ d, size, style = {} }) {
|
||||
const s = {
|
||||
fontSize: getFontSize(size),
|
||||
display: 'inline-block',
|
||||
@@ -30,13 +26,7 @@ export default function SvgIcon({
|
||||
};
|
||||
return (
|
||||
<i style={s}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 16 16"
|
||||
fill="currentColor"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor">
|
||||
<path d={d} />
|
||||
</svg>
|
||||
</i>
|
||||
|
||||
@@ -2,6 +2,7 @@ import SvgIcon from './SvgIcon';
|
||||
|
||||
export default function Unlock() {
|
||||
return SvgIcon({
|
||||
d: 'M2.5,7 L11,7 C11.5522847,7 12,7.44771525 12,8 L12,15 C12,15.5522847 11.5522847,16 11,16 L1,16 C0.44771525,16 0,15.5522847 0,15 L0,8 C0,7.44771525 0.44771525,7 1,7 L1,4.98151367 C1,2.23029964 3.23857625,0 6,0 C8.4241995,0 10.4454541,1.71883353 10.9029715,4 L9.34209114,4 C8.9671727,2.54028848 7.9088888,1.5 6,1.5 C3.54860291,1.5 2.5,3.21561511 2.5,5.33193359 L2.5,7 Z',
|
||||
d:
|
||||
'M2.5,7 L11,7 C11.5522847,7 12,7.44771525 12,8 L12,15 C12,15.5522847 11.5522847,16 11,16 L1,16 C0.44771525,16 0,15.5522847 0,15 L0,8 C0,7.44771525 0.44771525,7 1,7 L1,4.98151367 C1,2.23029964 3.23857625,0 6,0 C8.4241995,0 10.4454541,1.71883353 10.9029715,4 L9.34209114,4 C8.9671727,2.54028848 7.9088888,1.5 6,1.5 C3.54860291,1.5 2.5,3.21561511 2.5,5.33193359 L2.5,7 Z',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,9 +3,4 @@ import ChevronLeft from '@material-ui/icons/ChevronLeft';
|
||||
import Brightness3 from '@material-ui/icons/Brightness3';
|
||||
import WbSunny from '@material-ui/icons/WbSunny';
|
||||
|
||||
export {
|
||||
ChevronRight,
|
||||
ChevronLeft,
|
||||
Brightness3,
|
||||
WbSunny,
|
||||
};
|
||||
export { ChevronRight, ChevronLeft, Brightness3, WbSunny };
|
||||
|
||||
@@ -33,11 +33,12 @@ describe('resolver', () => {
|
||||
});
|
||||
|
||||
it('should throw when reference is cyclical', () => {
|
||||
const fn = () => resolver({
|
||||
foo: {
|
||||
bar: '4px $foo.bar',
|
||||
},
|
||||
});
|
||||
const fn = () =>
|
||||
resolver({
|
||||
foo: {
|
||||
bar: '4px $foo.bar',
|
||||
},
|
||||
});
|
||||
expect(fn).to.throw('Cyclical reference for "$foo.bar"');
|
||||
});
|
||||
});
|
||||
@@ -49,9 +50,11 @@ describe('resolver', () => {
|
||||
fontFamily: 'Arial',
|
||||
},
|
||||
});
|
||||
expect(r.resolve({
|
||||
font: '16px $typography.fontFamily',
|
||||
})).to.eql({
|
||||
expect(
|
||||
r.resolve({
|
||||
font: '16px $typography.fontFamily',
|
||||
})
|
||||
).to.eql({
|
||||
font: '16px Arial',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,14 +5,9 @@ export default {
|
||||
fontWeightLight: 300,
|
||||
fontWeightRegular: 400,
|
||||
fontWeightMedium: 600,
|
||||
fontFamily: [
|
||||
'"Source Sans Pro"',
|
||||
'"Segoe UI"',
|
||||
'"Helvetica Neue"',
|
||||
'-apple-system',
|
||||
'Arial',
|
||||
'sans-serif',
|
||||
].join(','),
|
||||
fontFamily: ['"Source Sans Pro"', '"Segoe UI"', '"Helvetica Neue"', '-apple-system', 'Arial', 'sans-serif'].join(
|
||||
','
|
||||
),
|
||||
button: {
|
||||
textTransform: 'initial',
|
||||
fontWeight: 400,
|
||||
|
||||
@@ -1,18 +1,5 @@
|
||||
import {
|
||||
ThemeProvider,
|
||||
useTheme,
|
||||
StylesProvider,
|
||||
createGenerateClassName,
|
||||
makeStyles,
|
||||
} from '@material-ui/styles';
|
||||
import { ThemeProvider, useTheme, StylesProvider, createGenerateClassName, makeStyles } from '@material-ui/styles';
|
||||
|
||||
import createTheme from './create';
|
||||
|
||||
export {
|
||||
createTheme,
|
||||
useTheme,
|
||||
makeStyles,
|
||||
ThemeProvider,
|
||||
StylesProvider,
|
||||
createGenerateClassName,
|
||||
};
|
||||
export { createTheme, useTheme, makeStyles, ThemeProvider, StylesProvider, createGenerateClassName };
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user