@things-factory/work-shift 10.1.33 → 10.1.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/pages/work-shift.d.ts +18 -102
- package/dist-client/pages/work-shift.js +165 -781
- package/dist-client/pages/work-shift.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/controllers/work-shift-range.d.ts +25 -9
- package/dist-server/controllers/work-shift-range.js +49 -196
- package/dist-server/controllers/work-shift-range.js.map +1 -1
- package/dist-server/controllers/work-shift-schedule.d.ts +2 -0
- package/dist-server/controllers/work-shift-schedule.js +9 -18
- package/dist-server/controllers/work-shift-schedule.js.map +1 -1
- package/dist-server/service/index.d.ts +5 -2
- package/dist-server/service/index.js +3 -0
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/work-shift/index.d.ts +4 -4
- package/dist-server/service/work-shift/index.js +4 -3
- package/dist-server/service/work-shift/index.js.map +1 -1
- package/dist-server/service/work-shift/shift-occurrence.d.ts +19 -0
- package/dist-server/service/work-shift/shift-occurrence.js +34 -0
- package/dist-server/service/work-shift/shift-occurrence.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-arrangement.d.ts +10 -0
- package/dist-server/service/work-shift/work-shift-arrangement.js +40 -0
- package/dist-server/service/work-shift/work-shift-arrangement.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-content.d.ts +15 -0
- package/dist-server/service/work-shift/work-shift-content.js +55 -0
- package/dist-server/service/work-shift/work-shift-content.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-lifecycle-resolver.d.ts +60 -0
- package/dist-server/service/work-shift/work-shift-lifecycle-resolver.js +77 -0
- package/dist-server/service/work-shift/work-shift-lifecycle-resolver.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-lifecycle.d.ts +130 -0
- package/dist-server/service/work-shift/work-shift-lifecycle.js +508 -0
- package/dist-server/service/work-shift/work-shift-lifecycle.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-mutation.js +9 -42
- package/dist-server/service/work-shift/work-shift-mutation.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-query.js +30 -15
- package/dist-server/service/work-shift/work-shift-query.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-revision-service.d.ts +29 -65
- package/dist-server/service/work-shift/work-shift-revision-service.js +67 -167
- package/dist-server/service/work-shift/work-shift-revision-service.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-revision.d.ts +78 -62
- package/dist-server/service/work-shift/work-shift-revision.js +303 -82
- package/dist-server/service/work-shift/work-shift-revision.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-type.d.ts +0 -5
- package/dist-server/service/work-shift/work-shift-type.js +1 -16
- package/dist-server/service/work-shift/work-shift-type.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/helps/page/work-shift.ko.md +19 -3
- package/helps/page/work-shift.md +17 -9
- package/package.json +8 -5
- package/dist-server/service/work-shift/work-shift-revision-query.d.ts +0 -20
- package/dist-server/service/work-shift/work-shift-revision-query.js +0 -74
- package/dist-server/service/work-shift/work-shift-revision-query.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work-shift.js","sourceRoot":"","sources":["../../client/pages/work-shift.ts"],"names":[],"mappings":";AAAA,OAAO,uCAAuC,CAAA;AAE9C,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAExD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEzF,OAAO,EAAa,gBAAgB,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAuCxF,MAAM,YAAY,GAAG,EAAE,CAAA;AACvB,MAAM,WAAW,GAAG,EAAE,GAAG,YAAY,CAAA;AAGrC,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,QAAQ;IAAhC;;QAqRmB,eAAU,GAAU,EAAE,CAAA;QACvC;;;;;;;WAOG;QACc,UAAK,GAAU,EAAE,CAAA;QACjB,cAAS,GAAU,EAAE,CAAA;QAEtC,4CAA4C;QAC3B,iBAAY,GAAG,EAAE,CAAA;IAsdpC,CAAC;aAvvBQ,WAAM,GAAG;QACd,iFAAiF;QACjF,kBAAkB;QAClB,eAAe;QACf,kBAAkB;QAClB,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4QF;KACF,AAlRY,CAkRZ;IAiBD;;;;;;OAMG;IACH,IAAI,OAAO;QACT,OAAO;YACC;;;SAGH;YACH,KAAK,EAAE,UAAU;YACvB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;YAC9B,IAAI,EAAE,iBAAiB;SACxB,CAAA;IACH,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;;;;;;;;oDAUqC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;qBAG/D,IAAI,CAAC,UAAU;sBACd,CAAC,KAAU,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;;;YAGzE,IAAI,CAAC,KAAK,EAAE;YACZ,IAAI,CAAC,QAAQ,EAAE;;;UAGjB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA,wBAAwB,IAAI,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,aAAa,EAAE;;4BAE1E,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,aAAa,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE;;KAEhF,CAAA;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK;QACX,OAAO,IAAI,CAAA;;cAED,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAC;cACzC,OAAO,CAAC,CAAC,CAAC,qCAAqC,CAAC;cAChD,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC;;KAEjD,CAAA;IACH,CAAC;IAED;;;;;;;OAOG;IACK,QAAQ;QACd,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAExC,OAAO,IAAI,CAAA;;8BAEe,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;;;qDAGV,CAAC,KAAK,YAAY,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;YACzF,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;;;;qDAIc,KAAK,YAAY,IAAI,CAAC,uBAAuB;YACtF,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;;;;;mBAKtB,IAAI,CAAC,YAAY;mBACjB,CAAC,KAAU,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;;;8CAG7B,IAAI,CAAC,KAAK;YAC5C,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,kBAAkB,CAAC;;;KAGtE,CAAA;IACH,CAAC;IAED,gEAAgE;IACxD,uBAAuB;QAC7B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,CAAA;QAC9C,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAExB,IAAI,CAAC,YAAY,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,GAAG,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAC7G,CAAC;IAED,8CAA8C;IACtC,KAAK;QACX,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,EAAE,CAAA;IACrE,CAAC;IAED;;;;;OAKG;IACK,aAAa;QACnB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACjC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,IAAI,IAAI,EAAE,CACpF,CAAA;QAED,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,CAAA;QACX,CAAC;QAED,OAAO,IAAI,CAAA;QACP,OAAO,CAAC,CAAC,CAAC,+BAA+B,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;WAC9E,CAAA;IACT,CAAC;IAED;;;;;OAKG;IACK,OAAO;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAA;IAC/D,CAAC;IAED,gCAAgC;IACxB,aAAa;QACnB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS;aAC5B,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;aAC1D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QAE5F,OAAO,IAAI,CAAA;;kDAEmC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC;;UAE9E,QAAQ,CAAC,MAAM;YACf,CAAC,CAAC,QAAQ,CAAC,GAAG,CACV,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAA;;;yCAGW,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;qCAC5D,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC3C,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC;;;oBAG3C,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,WAAW,CAAC;;eAEnE,CACF;YACH,CAAC,CAAC,IAAI,CAAA,sBAAsB,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,QAAQ;;KAE3E,CAAA;IACH,CAAC;IAED,oCAAoC;IAC5B,QAAQ;QACd,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAiB,CAAA;QAE5C,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,IAAI,CAAA;kDACiC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;6BACtD,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC;iBAChD,CAAA;QACb,CAAC;QAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;QACzC,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QAE7B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,uDAAuD;YACvD,OAAO,IAAI,CAAA;kDACiC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;UACzE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAA,wBAAwB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC;iBAC/E,CAAA;QACb,CAAC;QAED,OAAO,IAAI,CAAA;;kDAEmC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;UACzE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC;UAC3B,OAAO,GAAG,WAAW;YACrB,CAAC,CAAC,IAAI,CAAA;gBACA,OAAO,CAAC,CAAC,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,GAAG,YAAY,CAAC,EAAE,CAAC;mBACrF;YACT,CAAC,CAAC,EAAE;UACJ,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAA,wBAAwB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC;UACtF,CAAC,QAAQ,CAAC,MAAM,IAAI,OAAO,IAAI,WAAW;YAC1C,CAAC,CAAC,IAAI,CAAA,wBAAwB,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC,QAAQ;YAClF,CAAC,CAAC,EAAE;;KAET,CAAA;IACH,CAAC;IAED;;;;;OAKG;IACK,IAAI,CACV,MAAmB,EACnB,WAAgD,EAAE,EAClD,UAAuB,SAAS;QAEhC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QAE7B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,CAAA;QACX,CAAC;QAED,OAAO,IAAI,CAAA;;yCAE0B,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;;YAE5E,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAA,SAAS,SAAS,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC;;;KAGrG,CAAA;IACH,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,MAAmB,EAAE,QAA6C,EAAE,KAAiC;QAClH,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,CAAA;QACX,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAE7F,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACxB,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YAChF,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YAE1E,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;gBACjE,OAAO,EAAE,CAAA;YACX,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;YAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;YAE3C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBAClB,OAAO,EAAE,CAAA;YACX,CAAC;YAED,MAAM,KAAK,GAAG,GAAG,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAA;YAE3E,OAAO,IAAI,CAAA;;wBAEO,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;sBAC7B,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC,GAAG,GAAG,YAAY,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,GAAG;gBACtG,KAAK;;UAEX,KAAK;aACF,CAAA;QACT,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,WAAW,CAAC,OAAoD;QACtE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;QAE3D,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC3B,OAAO,OAAO,CAAC,CAAC,CAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACjG,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACrG,CAAC;QAED,OAAO,OAAO,CAAC,CAAC,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IACvE,CAAC;IAED;;;;;OAKG;IACK,OAAO;QACb,sDAAsD;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QAEpE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,IAAI,CAAA;;oDAEmC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;+BACrD,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;;OAE1D,CAAA;QACH,CAAC;QAED,OAAO,IAAI,CAAA;;kDAEmC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;UACxE,IAAI,CAAC,GAAG,CACR,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAA;;;qCAGW,UAAU,CAAC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC;sCACvD,QAAQ,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE;;gBAElD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC;;WAE9D,CACF;;KAEJ,CAAA;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAY,EAAE,KAAU,EAAE,MAAW;QACrD,mCAAmC;QACnC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QACnB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QAExB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;gBAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;SAuBT;gBACD,WAAW,EAAE,UAAU;aACxB,CAAC,CAAA;YAEF,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAA;YAChD,qDAAqD;YACrD,IAAI,CAAC,KAAK,GAAG,EAAE,CAAA;YACf,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE,CAAA;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,8CAA8C;YAC9C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAA;YAC3D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,QAAQ;QACpB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QAExB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,MAAM,CAAC;gBAClB,QAAQ,EAAE,GAAG,CAAA;;;;;;;SAOZ;gBACD,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE;aACnF,CAAC,CAAA;YAEF,IAAI,CAAC,YAAY,GAAG,EAAE,CAAA;YACtB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QACnB,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,0DAA0D;YAC1D,IAAI,CAAC,OAAO,GAAG,KAAK,EAAE,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAA;YACjF,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,EAAU;QAC7B,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QAExB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,MAAM,CAAC;gBAClB,QAAQ,EAAE,GAAG,CAAA;;;;SAIZ;gBACD,SAAS,EAAE,EAAE,EAAE,EAAE;aAClB,CAAC,CAAA;YAEF,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QACnB,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,GAAG,KAAK,EAAE,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAA;YAChF,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QAExB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,MAAM,CAAC;gBAClB,QAAQ,EAAE,GAAG,CAAA;;;;;;;;;;SAUZ;gBACD,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE;aACvC,CAAC,CAAA;YAEF,0DAA0D;YAC1D,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAA;YAC3D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;;AAlegB;IAAhB,KAAK,EAAE;;6CAA+B;AAStB;IAAhB,KAAK,EAAE;;wCAA0B;AACjB;IAAhB,KAAK,EAAE;;4CAA8B;AACrB;IAAhB,KAAK,EAAE;;0CAAyB;AAEhB;IAAhB,KAAK,EAAE;;+CAA0B;AAlS9B,SAAS;IADd,aAAa,CAAC,YAAY,CAAC;GACtB,SAAS,CAwvBd;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAE3C,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAC1E,CAAC;AAED,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE,CAAA;AACpC,CAAC;AAED;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,IAAa,EAAE,EAAW;IAC1C,IAAI,IAAI,KAAK,SAAS,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QAC3C,OAAO,EAAE,CAAA;IACX,CAAC;IAED,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;IACzF,CAAC;IAED,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC,EAAE,CAAA;AAC9C,CAAC;AAED,sCAAsC;AACtC,SAAS,SAAS,CAAC,MAAc;IAC/B,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;IAE/C,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAA;AACxG,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAAC,MAAc;IAC/B,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;IAE9B,OAAO,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAChF,CAAC;AAED,0DAA0D;AAC1D,SAAS,IAAI,CAAC,IAAY;IACxB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAE3C,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;AAC1E,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,UAAU,CAAC,IAAa,EAAE,EAAW;IAC5C,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAA;IACxB,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAA;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,EAAE,KAAK,GAAG,CAAC,YAAY,EAAE,CAAA;IAE3D,MAAM,KAAK,GAAG,CAAC,EAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;IAE/F,OAAO,OAAO;QACZ,CAAC,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE;QACrE,CAAC,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAA;AACzG,CAAC;AAED,SAAS,GAAG,CAAC,KAAc;IACzB,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACnF,CAAC;AAED,mDAAmD;AACnD,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAoB,CAAA;IAC7B,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAEhC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAAsB,CAAC,CAAC,CAAC,SAAS,CAAA;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,CAAA","sourcesContent":["import '@operato/input/ox-input-work-shift.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { PageView } from '@operato/shell'\nimport { CommonHeaderStyles, DocumentPageStyles, ScrollbarStyles } from '@operato/styles'\n\nimport { ShiftLike, coverageProblems, coveredMinutes, cycleOf } from '../shift-coverage'\n\n/**\n * 근무 교대 — **편성을 적고, 그것이 말이 되는지 보고, 예전 편성을 되짚는다.**\n *\n * ── 왜 목록만으로는 안 되나 ────────────────────────────────────────────────\n * 편성을 줄로만 보여 주면 **틈과 겹침이 안 보인다.** 22:00 에 끝나고 23:00 에 시작하는 것을 사람이\n * 눈으로 세어야 한다. 그 틈에 일어난 일은 어느 교대에도 속하지 않아, 그 시각을 물은 쪽은 조업일만 받고\n * 교대 이름은 못 받는다.\n *\n * 겹치면 그 시간의 일이 **먼저 걸린 교대**로 간다. 편성을 적은 사람은 그렇게 되는 줄 모른다.\n *\n * ── 앞으로 쓸 편성을 미리 적는다 ───────────────────────────────────────────\n * 「다음 달 1일부터 3교대」를 예고해 두면 그날이 올 때 **저절로** 그 편성이 답이 된다. 예고가 없으면\n * 바뀌는 날 자정에 사람이 손으로 고쳐야 하고, 그 시각에 도는 창이 어긋난다.\n *\n * 예고분이 이미 적용 중이면 **편집기의 내용은 지금 쓰는 편성이 아니다.** 그 사실을 화면이 말한다 —\n * 말하지 않으면 사람이 편집기를 고치고 저장했는데 아무것도 안 바뀐 것처럼 보인다.\n *\n * ── 예전 편성을 보인다 ─────────────────────────────────────────────────────\n * 저장이 그 도메인의 교대를 전부 지우고 다시 넣기 때문에, 앞서는 바꾸는 순간 이전 편성이 사라졌다.\n * 이제 바뀌기 전의 한 벌을 남긴다(`WorkShiftRevision`). 이 화면이 그것을 읽는 유일한 자리다 — 남기기만\n * 하고 보여 주지 않으면 남긴 적이 없는 것과 같다.\n */\n/**\n * 띠가 어느 때의 편성인가 — **색과 두께가 그것을 말한다.**\n *\n * 셋이 한 화면에 나란히 있으므로 같은 모양이면 어느 것이 지금 쓰는 것인지 매번 제목을 되짚어야 한다.\n *\n * 눈금은 셋 다 단다. **편성마다 한 바퀴가 시작하는 시각이 다르다** — 지금은 06:00, 예정은 07:00,\n * 이전은 08:00 에서 시작한다. 눈금이 없으면 같은 자리의 색이 서로 다른 시각을 가리키는데 그것을\n * 알아챌 길이 없다.\n *\n * current 지금 쓰는 것 가장 진하고 가장 두껍다\n * scheduled 아직 안 온 것 같은 색을 옅게 · 점선 테두리(색을 못 가르는 사람에게도 「아직」이 전해진다)\n * past 지나간 것 회색. 색을 뺀다\n */\ntype BandVariant = 'current' | 'scheduled' | 'past'\n\nconst HOUR_MINUTES = 60\nconst DAY_MINUTES = 24 * HOUR_MINUTES\n\n@customElement('work-shift')\nclass WorkShift extends PageView {\n static styles = [\n /* The frame owns the page shell and the reading column (ADR-0060 decision 8). */\n DocumentPageStyles,\n ScrollbarStyles,\n CommonHeaderStyles,\n css`\n :host {\n color: var(--ui-ink);\n }\n\n /*\n * 편집기는 **입력칸이지 이 화면의 내용이 아니다.** 무게를 낮춘다 — 앞서는 화면의 절반을 차지하고\n * 가장 큰 글씨를 쓰고 있었는데, 정작 사람이 보아야 할 것은 그 아래 배치 띠다.\n *\n * 안쪽은 다른 패키지의 그림자 DOM 이라 손대지 못한다. 바깥에서 할 수 있는 것만 한다.\n */\n ox-input-work-shift {\n overflow-y: auto;\n font-size: var(--ui-t-body);\n }\n\n /*\n * 하루를 가로로 펴서 어디가 비었는지 눈에 보이게 한다.\n *\n * 틈은 **칠하지 않고 사선 무늬**로 둔다. 아무것도 없는 것과 「여기가 틈이다」는 눈에 다르게\n * 보여야 하고, 색으로만 가르면 색을 못 가르는 사람에게 전해지지 않는다.\n */\n /* 이 화면의 답이 여기 있다. 다른 것보다 크고 조용하게 둔다. */\n .band {\n position: relative;\n height: 52px;\n border-radius: var(--ui-r-small);\n border: 1px solid var(--ui-line);\n background-color: var(--ui-panel);\n background-image: repeating-linear-gradient(\n 45deg,\n transparent 0 5px,\n var(--ui-line) 5px 6px\n );\n overflow: hidden;\n }\n\n /*\n * 조각 안의 글자는 **폭을 재서 가르지 않는다.** overflow: hidden 에 맡기면 넓을 때는 이름과\n * 시각이, 좁을 때는 이름만, 아주 좁을 때는 아무것도 안 보인다 — 저절로 세 단계가 된다.\n *\n * 그래서 조각마다 title 속성을 붙인다. 좁아서 안 보일 때 그것이 유일한 길이다.\n */\n .band .piece {\n position: absolute;\n top: 0;\n bottom: 0;\n background-color: var(--ui-accent);\n color: #fff;\n font-size: var(--ui-t-small);\n line-height: 52px;\n text-align: center;\n white-space: nowrap;\n overflow: hidden;\n /*\n * 조각끼리 붙어 있으면 한 덩어리로 보인다. 경계를 **조각 안쪽에** 긋는다 — 사이를 벌리면\n * 그 틈이 「덮이지 않은 시간」으로 읽힌다. 그 둘은 반대되는 사실이다.\n */\n box-shadow: inset -2px 0 0 var(--ui-panel), inset 2px 0 0 var(--ui-panel);\n }\n\n /* 겹친 조각은 색과 **무늬**로 함께 표시한다 — 색만으로는 못 가르는 사람이 있다. */\n .band .piece[data-overlap] {\n background-color: var(--ui-warn);\n background-image: repeating-linear-gradient(\n -45deg,\n transparent 0 4px,\n rgba(255, 255, 255, 0.35) 4px 6px\n );\n }\n\n /*\n * 두께가 중요도다. 앞서 표 안에 넣느라 22px 로 눌러 두었더니 **교대 이름이 잘려 읽히지 않았다** —\n * 이 띠들이 있는 이유가 「그때 편성이 어땠나」를 한눈에 보는 것인데, 읽을 수 없으면 있으나 마나다.\n */\n .band[data-variant='scheduled'] {\n height: 42px;\n }\n\n .band[data-variant='past'] {\n height: 34px;\n }\n\n .band[data-variant='scheduled'] .piece {\n line-height: 42px;\n font-size: var(--ui-t-small);\n /* 같은 색을 옅게 — 같은 것인데 아직 안 왔다는 뜻이다. */\n background-color: color-mix(in srgb, var(--ui-accent) 42%, var(--ui-panel));\n color: var(--ui-ink);\n border: 1px dashed color-mix(in srgb, var(--ui-accent) 70%, transparent);\n box-sizing: border-box;\n }\n\n .band[data-variant='past'] .piece {\n line-height: 34px;\n font-size: var(--ui-t-micro);\n /* 지나간 것은 색을 뺀다. 지금 쓰는 것과 다투지 않게. */\n background-color: color-mix(in srgb, var(--ui-muted) 45%, var(--ui-panel));\n color: var(--ui-ink);\n }\n\n .ticks {\n display: flex;\n justify-content: space-between;\n font-size: var(--ui-t-micro);\n color: var(--ui-muted);\n font-variant-numeric: tabular-nums;\n margin-top: 2px;\n }\n\n /* 아무 말이 없으면 「확인했는데 문제가 없다」와 「아직 안 봤다」가 같아 보인다. */\n .settled {\n border-left: 3px solid var(--ui-good);\n padding: var(--spacing-small) var(--spacing-medium);\n font-size: var(--ui-t-body);\n color: var(--ui-muted);\n }\n\n .finding {\n border-left: 3px solid var(--ui-warn);\n background-color: var(--ui-panel);\n padding: var(--spacing-small) var(--spacing-medium);\n font-size: var(--ui-t-body);\n line-height: 1.7;\n }\n\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--ui-t-body);\n }\n\n th {\n text-align: left;\n font-weight: 500;\n font-size: var(--ui-t-micro);\n color: var(--ui-muted);\n padding: 4px 8px;\n border-bottom: 1px solid var(--ui-line);\n }\n\n td {\n padding: 5px 8px;\n border-bottom: 1px solid var(--ui-panel);\n vertical-align: top;\n }\n\n .quiet {\n color: var(--ui-muted);\n }\n\n /* 한 편성이 한 덩어리다 — 시각과 띠가 붙어 있어야 어느 띠가 언제 것인지 갈린다. */\n .entry {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: var(--spacing-small) 0;\n border-bottom: 1px solid var(--ui-line-soft);\n }\n\n .entry:last-of-type {\n border-bottom: none;\n }\n\n .entry-head {\n display: flex;\n align-items: center;\n gap: var(--spacing-medium);\n font-size: var(--ui-t-body);\n }\n\n .entry-head .when {\n font-variant-numeric: tabular-nums;\n }\n\n\n .entry-head button {\n margin-left: auto;\n }\n\n /* 편집기 바로 아래 — 무엇을 내보내는지가 바로 위에 있다. */\n /*\n * 윗쪽은 **고치는 자리**, 아랫쪽은 **보는 자리**다. 그 경계를 선 하나로 그으면 어느 쪽에 속하는지\n * 애매한 것이 생긴다 — 실제로 적용 줄 위에 선을 두었더니 그 줄이 정보 영역으로 밀려 보였다.\n * 적용 줄은 위 편집기의 내용을 내보내는 자리이므로 편집에 속한다.\n *\n * 선 대신 **면**으로 가른다. 고치는 것은 한 판 위에 함께 얹히고, 보는 것은 바탕 위에 놓인다.\n */\n .editing {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-small);\n padding: var(--spacing-medium);\n /*\n * --ui-panel 은 바탕과 거의 같은 색이라 면을 깔아도 경계가 안 보였다. 강조색을 아주 옅게\n * 섞어 **손대는 자리**임을 드러낸다 — 아래 정보 영역은 바탕 그대로 둔다.\n */\n background-color: color-mix(in srgb, var(--ui-accent) 7%, var(--ui-bg));\n border: 1px solid color-mix(in srgb, var(--ui-accent) 35%, transparent);\n border-radius: var(--ui-r);\n }\n\n /* 두 영역 사이는 선이 아니라 **빈 자리**가 가른다. */\n .info {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-large);\n margin-top: var(--spacing-medium);\n }\n\n .howto {\n margin: 0;\n padding-left: 1.1em;\n display: flex;\n flex-direction: column;\n gap: 2px;\n font-size: var(--ui-t-small);\n color: var(--ui-muted);\n line-height: 1.6;\n }\n\n /* 같은 판 안의 두 부분이라 선을 흐리게 — 가르는 것이 아니라 나누는 것이다. */\n .apply {\n display: flex;\n align-items: center;\n gap: var(--spacing-medium);\n flex-wrap: wrap;\n padding: var(--spacing-small) 0 0 0;\n border-top: 1px solid var(--ui-line-soft);\n }\n\n .choice {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: var(--ui-t-body);\n cursor: pointer;\n }\n\n .apply-button {\n margin-left: auto;\n background-color: var(--ui-accent) !important;\n color: #fff !important;\n border-color: transparent !important;\n min-height: 36px;\n padding: 0 var(--spacing-large) !important;\n font-weight: 600;\n }\n\n .apply input[type='datetime-local'],\n .apply button,\n table button {\n font: inherit;\n padding: 5px 10px;\n border-radius: var(--ui-r-small);\n border: 1px solid var(--ui-line);\n background-color: var(--ui-panel);\n color: var(--ui-ink);\n }\n\n .announce button:not(:disabled),\n table button {\n cursor: pointer;\n }\n\n .announce button:disabled {\n opacity: 0.45;\n }\n `\n ]\n\n @state() private workShifts: any[] = []\n /**\n * 편집기에서 지금 고치고 있는 편성 — **띠와 찾아낸 것은 이것을 본다.**\n *\n * 띠는 **저장하기 전에** 편성이 말이 되는지 보라고 만든 자리다. 저장된 값만 보면 저장한 뒤에야\n * 틈이 보이고, 그때는 이미 그 편성으로 실적이 쌓이기 시작한 뒤다.\n *\n * 편집기에 되먹이지 않는다. 되먹이면 글자를 칠 때마다 편집기의 값이 새로 설정되어 커서가 튄다.\n */\n @state() private draft: any[] = []\n @state() private revisions: any[] = []\n @state() private problem?: string\n /** 예고를 언제부터 적용할까. 비어 있으면 예고 버튼이 눌리지 않는다. */\n @state() private announceFrom = ''\n\n /**\n * 툴바에 동작을 두지 않는다.\n *\n * 이 화면의 동작은 **언제부터 쓸지와 함께 정해진다.** 툴바 버튼은 그 선택에서 멀리 떨어져 있어\n * 이름이 선택을 따라갈 수 없다 — 「수정」이라 적힌 단추가 예고를 하게 된다. 그래서 편집기 바로 아래,\n * 시점을 고르는 자리 옆에 하나만 둔다.\n */\n get context() {\n return {\n /*\n * 이 화면이 어떤 틀인가 — 동작 줄이 이것을 읽고 자기 오른쪽 끝을 내용에 맞춘다\n * (ADR-0060 결정 9 보탬). 안 적으면 창 폭이고, 그것은 작업면의 모양이다.\n */\n frame: 'document',\ntitle: i18next.t('title.work-shift'),\n help: 'page/work-shift'\n }\n }\n\n render() {\n return html`\n <div class=\"page\">\n <!--\n 제목과 동작 바를 여기 두지 않는다 — 셸이 이미 그린다.\n\n 제목은 context.title 이 페이지 제목 줄(또는 상단 앱 바)에 그리고, 동작 바는 contextToolbar\n 자리에 그린다. 여기 또 두면 제목이 위아래로 둘이고 같은 버튼이 두 벌이 된다.\n -->\n\n <div class=\"editing\">\n <header class=\"page-section-header\"><h3>${i18next.t('title.shift-editing')}</h3></header>\n\n <ox-input-work-shift\n .value=${this.workShifts}\n @change=${(event: any) => (this.draft = [...(event.target?.value ?? [])])}\n ></ox-input-work-shift>\n\n ${this.howTo()}\n ${this.applyBar()}\n </div>\n\n ${this.problem ? html`<div class=\"finding\">${this.problem}</div>` : ''} ${this.runningNotice()}\n\n <div class=\"info\">${this.coverage()} ${this.announcements()} ${this.history()}</div>\n </div>\n `\n }\n\n /**\n * 이 화면을 쓰는 법 — **보고도 모르는 것 셋만.**\n *\n * 화면을 보면 아는 것은 적지 않는다(「이름을 적으십시오」 같은 것). 적는 것은 화면에 답이 없는\n * 것이다 — 표의 날짜 칸이 무엇을 뜻하는지, 예정한 시각이 오면 누가 무엇을 해야 하는지, 지금 편성이\n * 어디로 가는지.\n *\n * 길어지면 아무도 안 읽는다. 세 줄에서 늘리지 않는다.\n */\n private howTo() {\n return html`\n <ul class=\"howto\">\n <li>${i18next.t('text.howto-crossing-midnight')}</li>\n <li>${i18next.t('text.howto-scheduled-applies-itself')}</li>\n <li>${i18next.t('text.howto-previous-is-kept')}</li>\n </ul>\n `\n }\n\n /**\n * 이 편성을 **언제부터 쓸까** — 저장과 예고가 같은 결정이라 한 자리에 둔다.\n *\n * 앞서 「수정」은 위 툴바에, 「예고」는 화면 맨 아래에 있었다. 둘은 같은 편성을 내보내는 같은 행위이고\n * **시점만 다르다.** 화면 양 끝에 떨어져 있으면 사람은 그 둘이 다른 일인 줄 안다.\n *\n * 시점을 고르는 자리를 편집기 바로 아래에 둔다 — 무엇을 내보내는지가 바로 위에 있다.\n */\n private applyBar() {\n const later = Boolean(this.announceFrom)\n\n return html`\n <div class=\"apply\">\n <span class=\"quiet\">${i18next.t('text.apply-from-when')}</span>\n\n <label class=\"choice\">\n <input type=\"radio\" name=\"when\" ?checked=${!later} @change=${() => (this.announceFrom = '')} />\n ${i18next.t('text.apply-now')}\n </label>\n\n <label class=\"choice\">\n <input type=\"radio\" name=\"when\" ?checked=${later} @change=${this.pickDefaultAnnounceTime} />\n ${i18next.t('text.apply-later')}\n </label>\n\n <input\n type=\"datetime-local\"\n .value=${this.announceFrom}\n @input=${(event: any) => (this.announceFrom = event.target.value)}\n />\n\n <button class=\"apply-button\" @click=${this.apply}>\n ${i18next.t(later ? 'button.announce-shift' : 'button.apply-now')}\n </button>\n </div>\n `\n }\n\n /** 「그때부터」를 고르면 시각 칸이 비어 있으면 안 된다 — 비어 있으면 무엇을 고른 것인지 알 수 없다. */\n private pickDefaultAnnounceTime() {\n if (this.announceFrom) {\n return\n }\n\n const from = new Date(Date.now() + 86_400_000)\n from.setMinutes(0, 0, 0)\n\n this.announceFrom = new Date(from.getTime() - from.getTimezoneOffset() * 60_000).toISOString().slice(0, 16)\n }\n\n /** 고른 시점으로 내보낸다. 두 길이 아니라 한 길에 시점이 붙은 것이다. */\n private apply() {\n return this.announceFrom ? this.announce() : this.updateWorkShift()\n }\n\n /**\n * 예고분이 이미 적용 중인가.\n *\n * 그렇다면 **편집기의 내용은 지금 쓰는 편성이 아니다.** 말하지 않으면 사람이 편집기를 고치고\n * 저장했는데 아무것도 안 바뀐 것처럼 보인다(저장은 그 예고분을 닫으므로 실제로는 바뀐다).\n */\n private runningNotice() {\n const running = this.revisions.find(\n revision => !revision.effectiveTo && new Date(revision.effectiveFrom) <= new Date()\n )\n\n if (!running) {\n return ''\n }\n\n return html`<div class=\"finding\">\n ${i18next.t('text.announced-set-is-running', { since: day(running.effectiveFrom) })}\n </div>`\n }\n\n /**\n * 지금 화면이 다루고 있는 편성.\n *\n * **띠가 보여 준 것과 저장·예고되는 것이 같아야 한다.** 다르면 사람은 띠에서 확인한 편성을 내보낸 줄\n * 알지만 실제로는 다른 것이 나간다 — 그러면 확인하는 자리를 둔 뜻이 없다.\n */\n private editing(): any[] {\n return this.draft.length ? this.draft : this.workShifts ?? []\n }\n\n /** 앞으로 쓸 편성 — 아직 시작하지 않은 것만. */\n private announcements() {\n const now = new Date()\n const upcoming = this.revisions\n .filter(revision => new Date(revision.effectiveFrom) > now)\n .sort((a, b) => new Date(a.effectiveFrom).getTime() - new Date(b.effectiveFrom).getTime())\n\n return html`\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('title.shift-announcements')}</h3></header>\n\n ${upcoming.length\n ? upcoming.map(\n revision => html`\n <div class=\"entry\">\n <div class=\"entry-head\">\n <span class=\"when\">${i18next.t('field.starts')} ${day(revision.effectiveFrom)}</span>\n <button @click=${() => this.cancel(revision.id)}>\n ${i18next.t('button.cancel-announcement')}\n </button>\n </div>\n ${this.band(parseShifts(revision.shifts) ?? [], [], 'scheduled')}\n </div>\n `\n )\n : html`<div class=\"quiet\">${i18next.t('text.no-announcements')}</div>`}\n </section>\n `\n }\n\n /** 편성이 하루를 어떻게 덮나 — 그리고 어디가 비었나. */\n private coverage() {\n const shifts = this.editing() as ShiftLike[]\n\n if (!shifts.length) {\n return html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('title.shift-coverage')}</h3></header>\n <div class=\"quiet\">${i18next.t('text.no-shifts-declared')}</div>\n </section>`\n }\n\n const problems = coverageProblems(shifts)\n const covered = coveredMinutes(shifts)\n const cycle = cycleOf(shifts)\n\n if (!cycle) {\n /* 읽을 수 있는 교대가 하나도 없다. 띠를 그리면 빈 띠가 「하루가 다 비었다」로 보인다. */\n return html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('title.shift-coverage')}</h3></header>\n ${problems.map(problem => html`<div class=\"finding\">${this.problemText(problem)}</div>`)}\n </section>`\n }\n\n return html`\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('title.shift-coverage')}</h3></header>\n ${this.band(shifts, problems)}\n ${covered < DAY_MINUTES\n ? html`<div class=\"finding\">\n ${i18next.t('text.shift-covers-less-than-a-day', { hours: round(covered / HOUR_MINUTES) })}\n </div>`\n : ''}\n ${problems.map(problem => html`<div class=\"finding\">${this.problemText(problem)}</div>`)}\n ${!problems.length && covered >= DAY_MINUTES\n ? html`<div class=\"settled\">${i18next.t('text.shift-covers-the-whole-day')}</div>`\n : ''}\n </section>\n `\n }\n\n /**\n * 띠 하나 — 지금 편성에도, 예고에도, 이력에도 같은 것을 쓴다.\n *\n * 편성을 글자로만 적으면 사람이 시각을 머리로 이어 붙여야 한다. 이력에서 「그때 편성이 어땠나」를\n * 보는 사람에게 그 수고를 다시 시킬 이유가 없다.\n */\n private band(\n shifts: ShiftLike[],\n problems: ReturnType<typeof coverageProblems> = [],\n variant: BandVariant = 'current'\n ) {\n const cycle = cycleOf(shifts)\n\n if (!cycle) {\n return ''\n }\n\n return html`\n <div>\n <div class=\"band\" data-variant=${variant}>${this.pieces(shifts, problems, cycle)}</div>\n <div class=\"ticks\">\n ${[0, 6, 12, 18, 24].map(hour => html`<span>${cycleTime(cycle.startMinute + hour * 60)}</span>`)}\n </div>\n </div>\n `\n }\n\n /**\n * 띠의 조각들 — **한 바퀴 위에 놓는다.**\n *\n * 자정을 왼쪽 끝으로 두면 야간 교대가 있는 공장에서 없는 틈이 보이고 있는 틈이 안 보인다. 첫 교대가\n * 시작하는 시각이 왼쪽 끝이고, 거기서 24시간이 오른쪽 끝이다.\n */\n private pieces(shifts: ShiftLike[], problems: ReturnType<typeof coverageProblems>, cycle: ReturnType<typeof cycleOf>) {\n if (!cycle) {\n return ''\n }\n\n const overlapping = new Set(problems.filter(p => p.kind === 'overlap').flatMap(p => p.names))\n\n return shifts.map(shift => {\n const from = Number(shift.fromDate ?? 0) * DAY_MINUTES + minutes(shift.fromTime)\n const to = Number(shift.toDate ?? 0) * DAY_MINUTES + minutes(shift.toTime)\n\n if (!Number.isFinite(from) || !Number.isFinite(to) || to <= from) {\n return ''\n }\n\n const left = Math.max(cycle.startMinute, from)\n const right = Math.min(cycle.endMinute, to)\n\n if (right <= left) {\n return ''\n }\n\n const label = `${shift.name} ${hhmm(shift.fromTime)}~${hhmm(shift.toTime)}`\n\n return html`<div\n class=\"piece\"\n ?data-overlap=${overlapping.has(shift.name)}\n style=\"left:${((left - cycle.startMinute) / DAY_MINUTES) * 100}%; width:${((right - left) / DAY_MINUTES) * 100}%\"\n title=${label}\n >\n ${label}\n </div>`\n })\n }\n\n private problemText(problem: ReturnType<typeof coverageProblems>[number]): string {\n const span = spanText(problem.fromMinute, problem.toMinute)\n\n if (problem.kind === 'gap') {\n return i18next.t('text.shift-gap', { span, before: problem.names[0], after: problem.names[1] })\n }\n\n if (problem.kind === 'overlap') {\n return i18next.t('text.shift-overlap', { span, first: problem.names[0], second: problem.names[1] })\n }\n\n return i18next.t('text.shift-not-a-span', { name: problem.names[0] })\n }\n\n /**\n * 예전 편성.\n *\n * **비어 있어도 절을 그린다.** 앞서 없으면 통째로 감췄는데, 이력을 찾으러 온 사람은 그때 비어 있는\n * 것인지 고장인지 알 길이 없다. 예고 절이 「없습니다」를 적는 것과도 앞뒤가 안 맞았다.\n */\n private history() {\n /* 끝난 것만 이력이다. 예고된 것은 위 절에 있다 — 한 표에 섞으면 앞뒤를 못 가른다. */\n const past = this.revisions.filter(revision => revision.effectiveTo)\n\n if (!past.length) {\n return html`\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('title.shift-history')}</h3></header>\n <div class=\"quiet\">${i18next.t('text.no-shift-history')}</div>\n </section>\n `\n }\n\n return html`\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('title.shift-history')}</h3></header>\n ${past.map(\n revision => html`\n <div class=\"entry\">\n <div class=\"entry-head\">\n <span class=\"when\">${periodText(revision.effectiveFrom, revision.effectiveTo)}</span>\n <span class=\"quiet\">${revision.creator?.name ?? ''}</span>\n </div>\n ${this.band(parseShifts(revision.shifts) ?? [], [], 'past')}\n </div>\n `\n )}\n </section>\n `\n }\n\n async pageUpdated(changes: any, after: any, before: any) {\n /* refresh always page revisited */\n if (this.active) {\n await this.load()\n }\n }\n\n private async load() {\n this.problem = undefined\n\n try {\n const response = await client.query({\n query: gql`\n query {\n workShifts(sortings: [{ name: \"fromDate\" }, { name: \"fromTime\" }]) {\n items {\n name\n fromDate\n fromTime\n toDate\n toTime\n }\n }\n workShiftRevisions(sortings: [{ name: \"effectiveFrom\", desc: true }], pagination: { limit: 30 }) {\n items {\n id\n effectiveFrom\n effectiveTo\n shifts\n creator {\n name\n }\n }\n }\n }\n `,\n fetchPolicy: 'no-cache'\n })\n\n this.workShifts = response.data.workShifts.items\n /* 새로 읽었으면 고치던 것은 없다 — 남겨 두면 저장한 내용이 아닌 것이 띠에 남는다. */\n this.draft = []\n this.revisions = response.data.workShiftRevisions?.items ?? []\n } catch (error) {\n /* 못 읽은 것을 빈 편성으로 두지 않는다 — 「아직 안 정했다」로 읽힌다. */\n this.problem = i18next.t('text.could-not-read-work-shifts')\n console.error(error)\n }\n }\n\n /**\n * 예고한다 — **위 편집기의 내용을 그 시각부터 쓰겠다는 뜻이다.**\n *\n * 편집기의 내용을 그대로 보내므로, 예고하기 전에 편집기가 앞으로 쓸 편성이어야 한다. 그 사실을 버튼\n * 옆에 적어 둔다.\n */\n private async announce() {\n this.problem = undefined\n\n try {\n await client.mutate({\n mutation: gql`\n mutation ($effectiveFrom: DateTimeISO!, $patches: [WorkShiftPatch!]!) {\n announceWorkShift(effectiveFrom: $effectiveFrom, patches: $patches) {\n id\n effectiveFrom\n }\n }\n `,\n variables: { effectiveFrom: new Date(this.announceFrom), patches: this.editing() }\n })\n\n this.announceFrom = ''\n await this.load()\n } catch (error: any) {\n /* 서버가 왜 막았는지 그대로 보인다 — 「저장 실패」로 뭉개면 무엇을 고쳐야 할지 알 수 없다. */\n this.problem = error?.message || i18next.t('text.could-not-announce-work-shifts')\n console.error(error)\n }\n }\n\n private async cancel(id: string) {\n this.problem = undefined\n\n try {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!) {\n cancelWorkShiftAnnouncement(id: $id)\n }\n `,\n variables: { id }\n })\n\n await this.load()\n } catch (error: any) {\n this.problem = error?.message || i18next.t('text.could-not-cancel-announcement')\n console.error(error)\n }\n }\n\n private async updateWorkShift() {\n this.problem = undefined\n\n try {\n await client.mutate({\n mutation: gql`\n mutation ($patches: [WorkShiftPatch!]!) {\n updateMultipleWorkShift(patches: $patches) {\n name\n fromDate\n fromTime\n toDate\n toTime\n }\n }\n `,\n variables: { patches: this.editing() }\n })\n\n /* 저장한 것을 그대로 믿지 않고 다시 읽는다 — 이력이 한 줄 늘었는지 이 화면이 보여야 한다. */\n await this.load()\n } catch (error) {\n this.problem = i18next.t('text.could-not-save-work-shifts')\n console.error(error)\n }\n }\n}\n\nfunction minutes(time: string): number {\n const parts = String(time ?? '').split(':')\n\n return parts.length < 2 ? NaN : Number(parts[0]) * 60 + Number(parts[1])\n}\n\nfunction round(value: number): number {\n return Math.round(value * 10) / 10\n}\n\n/**\n * 구간 하나를 사람이 읽는 말로.\n *\n * 양쪽이 다 다음 날이면 「익일」을 두 번 적지 않는다 — 「익일 02:00~익일 08:00」은 같은 말을 두 번\n * 하는 것이고, 읽는 사람이 두 날을 오가는 것으로 잘못 본다.\n */\nfunction spanText(from?: number, to?: number): string {\n if (from === undefined || to === undefined) {\n return ''\n }\n\n if (from >= 1440 && to >= 1440) {\n return i18next.t('text.next-day-time', { time: `${plainTime(from)}~${plainTime(to)}` })\n }\n\n return `${cycleTime(from)}~${cycleTime(to)}`\n}\n\n/** 24로 접은 시각. 「익일」 표시는 부르는 쪽이 붙인다. */\nfunction plainTime(minute: number): string {\n const wrapped = ((minute % 1440) + 1440) % 1440\n\n return `${String(Math.floor(wrapped / 60)).padStart(2, '0')}:${String(wrapped % 60).padStart(2, '0')}`\n}\n\n/**\n * 한 바퀴 안의 분을 **사람이 읽는 시각**으로.\n *\n * 한 바퀴는 첫 교대에서 시작하므로 그 안의 분은 24시간을 넘어간다. 그것을 그대로 적으면 `26:00` 이\n * 되는데, 그런 시각은 시계에 없다. 24로 접고 넘어간 것은 「익일」로 적는다.\n */\nfunction cycleTime(minute: number): string {\n const text = plainTime(minute)\n\n return minute >= 1440 ? i18next.t('text.next-day-time', { time: text }) : text\n}\n\n/** 초는 안 적는다 — 교대 경계에 초를 쓰는 공장은 없고, 그 자리를 이름이 쓰는 편이 낫다. */\nfunction hhmm(time: string): string {\n const parts = String(time ?? '').split(':')\n\n return parts.length < 2 ? String(time ?? '') : `${parts[0]}:${parts[1]}`\n}\n\n/**\n * 사용 기간 한 줄 — **같은 날이면 날짜를 두 번 적지 않는다.**\n *\n * 앞서 양쪽에 날짜와 초를 다 적었더니 한 줄이 너무 길어, 두 줄로 나눠 보았다. 그랬더니 옆의 이름이\n * 두 줄 사이에 떠서 더 어색했다. 줄을 나눌 일이 아니라 **적을 것을 줄일 일**이었다.\n *\n * 초는 적지 않는다. 편성이 언제부터 언제까지 쓰였나에 초는 뜻이 없다.\n */\nfunction periodText(from?: string, to?: string): string {\n if (!from || !to) {\n return ''\n }\n\n const start = new Date(from)\n const end = new Date(to)\n const lang = i18next.language || undefined\n const sameDay = start.toDateString() === end.toDateString()\n\n const clock = (at: Date) => at.toLocaleTimeString(lang, { hour: '2-digit', minute: '2-digit' })\n\n return sameDay\n ? `${start.toLocaleDateString(lang)} ${clock(start)} ~ ${clock(end)}`\n : `${start.toLocaleDateString(lang)} ${clock(start)} ~ ${end.toLocaleDateString(lang)} ${clock(end)}`\n}\n\nfunction day(value?: string): string {\n return value ? new Date(value).toLocaleString(i18next.language || undefined) : ''\n}\n\n/** 저장된 편성은 JSON 문자열로 온다(스칼라). 읽을 수 없으면 없다고 답한다. */\nfunction parseShifts(value: unknown): ShiftLike[] | undefined {\n if (Array.isArray(value)) {\n return value as ShiftLike[]\n }\n\n if (typeof value !== 'string') {\n return undefined\n }\n\n try {\n const parsed = JSON.parse(value)\n\n return Array.isArray(parsed) ? (parsed as ShiftLike[]) : undefined\n } catch {\n return undefined\n }\n}\n\nexport { WorkShift }\n"]}
|
|
1
|
+
{"version":3,"file":"work-shift.js","sourceRoot":"","sources":["../../client/pages/work-shift.ts"],"names":[],"mappings":"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","sourcesContent":["import gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { PageView } from '@operato/shell'\nimport { DocumentPageStyles, ScrollbarStyles } from '@operato/styles'\nimport { revisionText as t, revisionDate, revisionContents, revisionStyles } from '@things-factory/ops-master/dist-client/pages/master/revision-comparison.js'\nimport { localDateTime, isoFromLocal } from '@things-factory/ops-master/dist-client/pages/master/revision-view.js'\n\n@customElement('work-shift')\nexport class WorkShift extends PageView {\n static styles = [DocumentPageStyles, ScrollbarStyles, revisionStyles, css`\n .page { padding: 20px; display: grid; gap: 20px; min-width: 0; }\n section { border: 1px solid var(--ui-line); border-radius: 6px; padding: 16px; min-width: 0; }\n h2 { font-size: 18px; margin: 0 0 12px; }\n .bar, .fields { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }\n .fields label { display: grid; gap: 5px; flex: 1 1 200px; }\n input, select, textarea { font: inherit; padding: 6px 8px; border: 1px solid var(--ui-line); border-radius: 4px; background: var(--md-sys-color-surface); color: inherit; box-sizing: border-box; max-width: 100%; }\n input[type=time] { width: 105px; }\n .scroll table { min-width: 780px; }\n .week { display:flex; flex-wrap:wrap; gap:4px; max-width:210px; }\n .week label { white-space:nowrap; }\n .current { border-left: 4px solid var(--md-sys-color-primary); }\n .notice { padding:12px; background:var(--md-sys-color-surface-container); }\n `]\n @state() private overview: any\n @state() private draft: any\n @state() private message = ''\n @state() private busy = false\n @state() private statuses: Record<string, any> = {}\n private dirty = false\n get context(): any { return { title: i18next.t('title.work-shift'), frame: 'document', help: 'page/work-shift' } }\n async pageUpdated() { if (this.active && !this.dirty) await this.load() }\n private current() {\n const segment = this.overview?.schedule.find((s: any) => s.state === 'current')\n return segment && this.overview.revisions.find((r: any) => r.id === segment.revisionId)\n }\n private async run(action: () => Promise<void>) {\n this.busy = true; this.message = ''\n try { await action() } catch(e: any) { this.message = e.message }\n finally { this.busy = false }\n }\n private async load() {\n await this.run(async () => {\n const result = await client.query({ query: gql`query { workShiftRevisionOverview }`, fetchPolicy: 'no-cache' })\n if (result.errors?.length) throw new Error(result.errors[0].message)\n this.overview = result.data.workShiftRevisionOverview\n const statuses: Record<string, any> = {}\n for (const row of this.overview.revisions.filter((r: any) => r.activityInstanceId)) {\n let promise: Promise<any> | undefined\n document.dispatchEvent(new CustomEvent('master-change-status', { detail: { activityInstanceId: row.activityInstanceId, respondWith: (p: Promise<any>) => promise = p } }))\n if (promise) statuses[row.id] = await promise\n }\n this.statuses = statuses\n })\n }\n private begin(row = this.current()) {\n this.draft = { description: row?.description ?? '', timezone: row?.timezone ?? this.overview.timezone,\n shifts: structuredClone(row?.shifts ?? [{ name: '', fromDate: 0, fromTime: '08:00', toDate: 0, toTime: '16:00', daysOfWeek: '' }]),\n effectiveFrom: new Date().toISOString(), reason: '' }\n this.dirty = false\n }\n private change(field: string, value: any) { this.draft = { ...this.draft, [field]: value }; this.dirty = true }\n private changeShift(index: number, field: string, value: any) {\n this.change('shifts', this.draft.shifts.map((s: any, i: number) => i === index ? { ...s, [field]: value } : s))\n }\n private async save() {\n await this.run(async () => {\n const { description, timezone, shifts, effectiveFrom, reason } = this.draft\n const content = { description, timezone, shifts, effectiveFrom, reason }\n const editing = !!this.draft.id\n const response = await client.mutate({ mutation: editing\n ? gql`mutation($revisionId:String!,$editGeneration:Int!,$content:Object!){editWorkShiftDraft(revisionId:$revisionId,editGeneration:$editGeneration,content:$content)}`\n : gql`mutation($content:Object!){createWorkShiftDraft(content:$content)}`,\n variables: { content, ...(editing ? { revisionId: this.draft.id, editGeneration: this.draft.editGeneration } : {}) } })\n if (response.errors?.length) throw new Error(response.errors[0].message)\n this.draft = response.data[editing ? 'editWorkShiftDraft' : 'createWorkShiftDraft']\n this.dirty = false\n })\n if (!this.message) await this.load()\n }\n private async submit() {\n await this.run(async () => {\n if (this.overview.approvalRequired) {\n let promise: Promise<any> | undefined\n document.dispatchEvent(new CustomEvent('master-change-approval', { detail: {\n axis: 'workShift', revisionId: this.draft.id, editGeneration: this.draft.editGeneration,\n respondWith: (p: Promise<any>) => promise = p } }))\n if (!promise) throw new Error(t('approval-unavailable'))\n await promise\n } else {\n const result = await client.mutate({ mutation: gql`mutation($revisionId:String!,$editGeneration:Int!){publishWorkShiftDraft(revisionId:$revisionId,editGeneration:$editGeneration)}`,\n variables: { revisionId: this.draft.id, editGeneration: this.draft.editGeneration } })\n if (result.errors?.length) throw new Error(result.errors[0].message)\n }\n this.draft = undefined; this.dirty = false\n })\n if (!this.message) await this.load()\n }\n private rowStatus(row: any) {\n const segment = this.overview.schedule.find((s: any) => s.revisionId === row.id)\n return segment?.state ?? this.statuses[row.id]?.state ?? (row.frozenAt ? 'pending' : 'draft')\n }\n private weekdays(row: any, index: number) {\n const days = row.daysOfWeek ? row.daysOfWeek.split(',') : ['0','1','2','3','4','5','6']\n return html`<div class=\"week\">${['1','2','3','4','5','6','0'].map(day => html`<label><input type=\"checkbox\" .checked=${days.includes(day)}\n @change=${(e: any) => {\n const next = e.target.checked ? [...days,day] : days.filter(d => d !== day)\n if (!next.length) { e.target.checked = true; return }\n this.changeShift(index, 'daysOfWeek', next.length === 7 ? '' : [...new Set(next)].sort().join(','))\n }} />${t('weekday-' + day)}</label>`)}</div>`\n }\n render() {\n const current = this.current(), base = this.draft && this.overview?.revisions.find((r: any) => r.id === this.draft.baseRevisionId)\n return html`<div class=\"page\">\n <div class=\"bar\"><button ?disabled=${this.busy || this.dirty} @click=${() => this.load()}>${t('refresh')}</button>\n <button ?disabled=${this.busy || !this.overview || !!this.draft} @click=${() => this.begin()}>${t('create-change')}</button></div>\n ${this.message ? html`<p role=\"alert\">${this.message}</p>` : ''}\n <section class=\"current\"><h2>${t('current')}</h2>\n ${current ? html`<p>${t('revision-value',{n:current.revisionNumber})} · ${revisionDate(this.overview.schedule.find((s:any)=>s.state==='current').validFrom)}</p>${revisionContents(current,'workShift')}`\n : html`<p>${t('no-current')}</p>`}\n </section>\n ${this.draft ? html`<section><h2>${this.draft.id ? t('revision-value',{n:this.draft.revisionNumber}) : t('new')} · ${t(this.draft.id ? this.rowStatus(this.draft) : 'draft')}</h2>\n ${this.draft.frozenAt ? revisionContents(this.draft,'workShift') : html`\n <div class=\"fields\">${['description','timezone','reason'].map(field => html`<label>${t(field)}<input aria-label=${field} .value=${this.draft[field] ?? ''} @input=${(e:any)=>this.change(field,e.target.value)} /></label>`)}\n <label>${t('effectiveFrom')} · ${Intl.DateTimeFormat().resolvedOptions().timeZone}<input aria-label=\"effectiveFrom\" type=\"datetime-local\" .value=${localDateTime(this.draft.effectiveFrom)} @change=${(e:any)=>{try {this.change('effectiveFrom',isoFromLocal(e.target.value))} catch(err:any){this.message=err.message}}} /></label>\n </div>\n <div class=\"scroll\"><table><thead><tr>${['name','fromDate','fromTime','toDate','toTime','daysOfWeek'].map(f=>html`<th>${t(f)}</th>`)}<th></th></tr></thead><tbody>\n ${this.draft.shifts.map((row:any,index:number)=>html`<tr>\n <td><input aria-label=${'name-'+index} .value=${row.name} @input=${(e:any)=>this.changeShift(index,'name',e.target.value)} />\n <label>${t('description')}<input aria-label=${'description-'+index} .value=${row.description ?? ''} @input=${(e:any)=>this.changeShift(index,'description',e.target.value)} /></label></td>\n ${['from','to'].map(side=>html`<td><select aria-label=${side+'Date-'+index} .value=${String(row[side+'Date'])} @change=${(e:any)=>this.changeShift(index,side+'Date',Number(e.target.value))}>${[-1,0,1].map(d=>html`<option value=${d}>${t('day-offset-'+d)}</option>`)}</select></td>\n <td><input aria-label=${side+'Time-'+index} type=\"time\" .value=${row[side+'Time']} @input=${(e:any)=>this.changeShift(index,side+'Time',e.target.value)} /></td>`)}\n <td>${this.weekdays(row,index)}</td><td><button ?disabled=${this.draft.shifts.length===1} @click=${()=>this.change('shifts',this.draft.shifts.filter((_:any,i:number)=>i!==index))}>${t('remove')}</button></td>\n </tr>`)}\n </tbody></table></div><button @click=${()=>this.change('shifts',[...this.draft.shifts,{name:'',fromDate:0,fromTime:'16:00',toDate:1,toTime:'00:00',daysOfWeek:''}])}>${t('add-shift')}</button>\n <p class=\"notice\">${t('shift-impact')}</p>\n <div class=\"bar\"><button ?disabled=${this.busy} @click=${()=>this.save()}>${t('save-draft')}</button>\n <button class=\"primary\" ?disabled=${this.busy || this.dirty || !this.draft.id} @click=${()=>this.submit()}>${t(this.overview.approvalRequired?'request-approval':'publish')}</button></div>`}\n <button ?disabled=${this.busy} @click=${()=>{if(!this.dirty || window.confirm(t('discard-changes'))){this.draft=undefined;this.dirty=false}}}>${t('close-details')}</button>\n ${this.draft.id ? html`<ops-master-revision-comparison axis=\"workShift\" .before=${base} .after=${this.draft}></ops-master-revision-comparison>` : ''}\n </section>` : ''}\n ${this.overview ? html`<section><h2>${t('history')}</h2>${[...this.overview.revisions].reverse().map((row:any)=>{\n const period=this.overview.schedule.find((s:any)=>s.revisionId===row.id), status=this.statuses[row.id]\n return html`<div class=\"bar\"><button ?disabled=${this.dirty} @click=${()=>{this.draft=structuredClone(row);this.dirty=false}}>${t('revision-value',{n:row.revisionNumber})}</button><span class=\"pill\">${t(this.rowStatus(row))}</span>\n <span>${period ? html`${revisionDate(period.validFrom)} → ${period.validTo ? revisionDate(period.validTo) : t('until-change')}` : html`${t('effectiveFrom')}: ${revisionDate(row.effectiveFrom)}`}</span>\n ${status?.comment ? html`<span>${status.comment}</span>` : ''}${status?.open ? html`<button @click=${()=>status.open()}>${t('approval-detail')}</button>` : ''}\n <button ?disabled=${this.dirty} @click=${()=>this.begin(row)}>${t('create-change')}</button></div>`\n })}</section>` : ''}\n </div>`\n }\n}\n"]}
|